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; }