1、归并排序
分治思想:每次从中间分开为两个子问题,对每个子问题排序完成之后,将两个已排序的部分进行归并操作即得到最终排序的结果。
(1)如果数组S中元素个数为0或者1返回
(2)选取中间位置的元素下标,对左半部分SL递归排序,对右半部分SR递归排序
(3)将排好序的SL、SR进行归并后返回最终结果
平均时间复杂度O(NlogN),最坏情况也为O(NlogN),最好情况为O(N)。
C++模版实现:
template <typename T> void TMergeSort(vector<T> & arr, vector<T> &tmp, int left, int right) { if (left < right) { int mid = (left + right) / 2; TMergeSort(arr, tmp, left, mid); TMergeSort(arr, tmp, mid + 1, right); int leftPos = left, rightPos = mid + 1, tmpPos = left; while (leftPos <= mid && rightPos <= right) if (arr[leftPos] <= arr[rightPos]) tmp[tmpPos++] = arr[leftPos++]; else tmp[tmpPos++] = arr[rightPos++]; while (leftPos <= mid) tmp[tmpPos++] = arr[leftPos++]; while (rightPos <= right) tmp[tmpPos++] = arr[rightPos++]; for (int i = left; i <= right; i++) arr[i] = tmp[i]; } }
2、快速排序
分治思想:分为子问题的时候是随机分,找一个枢轴元素,将此元素的位置找到。随机分的方法也可以使用三数取中值方法,对第一个、最后一个、中间位置元素进行判断,选取大小为中间的元素为枢轴元素,这样可以节约14%左右的比较次数。也可以使用最不安全的分法,就是每次选取第一个元素为枢轴。
(1)如果数组S中元素个数为0或者1,返回
(2)用选定的方法选取一个枢轴元素v
(3)将S-{v}划分为两个不相交的集合,其中S+ = {x | x >= v},S- = {x | x <= v}
(4)对S+和S- 分别进行递归排序,S- 、v、S+即为排序的最终结果
平均时间复杂度为O(NlogN),最坏情况为O(N^2),最好情况为O(NlogN)。
C++模版实现如下:
template <typename T> void TQuickSort(vector<T> & p, int low, int high) { if (low < high) { int l = low, h = high, m = (low + high) / 2, p_index; //三数取中值方法选择枢轴 T pivot; if ((p[l] <= p[m] && p[m] <= p[h]) || (p[h] <= p[m] && p[m] <= p[l])) { pivot = p[m]; p_index = m; } if ((p[l] <= p[h] && p[h] <= p[m]) || (p[m] <= p[h] && p[h] <= p[l])) { pivot = p[h]; p_index = h; } if ((p[m] <= p[l] && p[l] <= p[h]) || (p[h] <= p[l] && p[l] <= p[m])) { pivot = p[l]; p_index = l; } while(l < h) { while (l < h && p[h] >= pivot) h--; p[p_index] = p[h]; p_index = h; while (l < h && p[l] < pivot) l++; p[p_index] = p[l]; p_index = l; } p[p_index] = pivot; TQuickSort(p, low, p_index); TQuickSort(p, p_index + 1, high); } }
原文地址:http://blog.csdn.net/u010487568/article/details/40629017