1、 歸並排序(merge sort)
歸並操作的工作原理如下:
1:申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合並后的序列;
2:設定兩個指針,最初位置分別為兩個已經排序序列的起始位置;
3:比較兩個指針所指向的元素,選擇相對小的元素放入到合並空間,並移動指針到下一位置;
重復步驟3直到某一指針超出序列尾。將另一序列剩下的所有元素直接復制到合並序列尾。
歸並排序的效率是比較高的,設數列長為 N,將數列分開成小數列一共要 logN 步,每步都是一個合並有序數列的過程,時間復雜度可以記為 O(N),故歸並排序的時間復雜度為 O(NlogN)。
class Solution { public: void mergeSort(int* data, int length) { if (data == nullptr || length <= 0) return; int* copy = new int[length]; for (int i = 0; i < length; ++i) copy[i] = data[i]; mergesort(data, copy, 0, length - 1); delete[] copy; } private: void mergesort(int* data, int* copy, int start, int end) { if (start == end) return; if (start < end) { int mid = ((end - start) >> 1) + start; mergesort(data, copy, start, mid); // 左邊有序 mergesort(data, copy, mid + 1, end); // 右邊有序 mergedata(data, copy, start, mid, end); // 將兩個有序數列合並 } } void mergedata(int* data, int* copy, int start, int mid, int end) { int i = start; int j = mid + 1; int k = 0; while (i <= mid && j <= end) { if (data[i] < data[j]) copy[k++] = data[i++]; else copy[k++] = data[j++]; } while (i <= mid) copy[k++] = data[i++]; while (j <= end) copy[k++] = data[j++]; for (int i = 0; i < k; ++i) data[start + i] = copy[i]; } };
測試用例:
void test() { int data[] = { 9, 8, 7, 8, 8, 3, 2, 1 }; //int data[] = { 1 }; int length = sizeof(data) / sizeof(int); Solution M; M.mergeSort(data, length); for (int i = 0; i < length; ++i) cout << data[i] << " "; cout << endl; }