排序(3)---归并排序

来源:互联网 发布:看图猜电影pc软件 编辑:程序博客网 时间:2024/06/06 02:27

归并排序

归并:将两个有序数组归并成为一个更大的有序数组。

归并排序是一种分治的思想,将数组分为两份在合并起来。优点是归并排序所需时间和NlogN成正比,主要缺点是所需的额外空间和N成正比。

归并排序主要分两种:

一、自定向下的归并排序

原来便是将数组以递归的形式依次向下分成两份,然后再将数组重下往上依次有序合并。

代码:

template<typename Item>void Merge(vector<Item>&a,vector<Item>aux, int lo, int mid, int hi){int i = lo, j = mid + 1;for (int k = lo; k <=hi; k++)if (i>mid)           aux[k] = a[j++];else if (j>hi)       aux[k] = a[i++];else if (a[j]<a[i])  aux[k] = a[j++];else                 aux[k] = a[i++];for (int k = lo; k <= hi;k++)a[k] = aux[k];}template<typename Item>void mergesort(vector<Item>&a, vector<Item>&aux,int lo, int hi){if (hi<=lo)return;//if (hi <= lo + 10){insertsort(a, lo, hi); return;}//改进,加快小数组排序int mid = lo + (hi - lo) / 2;mergesort(a, aux, lo, mid);mergesort(a, aux, mid + 1, hi);if (a[mid]>a[mid + 1])Merge(a, aux, lo, mid, hi);}template<typename Item>void mergesort(vector<Item>&a){int N = a.size();vector<Item>aux(N);mergesort(a,aux, 0, N-1);}

改进:

插入算法对小数组的排序速度是优于归并排序的。

所以我们将使用mergesort中被注销的代码,在数组长度小于十的时候使用insertsort。

template <typename Item>void eaxh(Item &a, Item &b){Item t = a;a = b;b = t;}template<typename Item>void insertsort(vector<Item>&a, int lo, int hi){for (int i = lo+1; i <= hi; ++i){Item temp = a[lo];int j;for ( j = i; j >= lo&&temp < a[j - 1]; --j)a[j] = a[j - i];a[j] = temp;}}

二、自底向上的归并排序

与上一种相反的排序方式,不使用递归,先将数组分为最小的单元,然后以循环的方式两两合并。

template<typename Item>void Merge_1(vector<Item>&a, vector<Item>&aux, int lo, int mid, int hi){int i = lo, j = mid + 1;for (int k = lo; k <= hi; k++)if (i>mid)           aux[k] = a[j++];else if (j>hi)       aux[k] = a[i++];else if (a[j]<a[i])  aux[k] = a[j++];else                aux[k] = a[i++];for (int i = lo; i <= hi; i++)a[i] = aux[i];}template<typename Item>void mergesort_1(vector<Item>&a){int N = a.size();vector<Item>aux(N);for (int sz = 1; sz<N; sz = sz + sz)for (int lo = 0; lo<N - sz; lo += sz + sz)Merge_1(a, aux, lo, lo + sz - 1, min(lo + sz + sz - 1, N - 1));}
归并是一种渐进最优的基于比较的排序算法。也就是说归并无论是的排序时间相对来说很稳定。

测试:

归并排序测试:算法|量级10100100010000100000自顶向下0.1050.1060.1150.33911.97改进0.1050.1040.1080.1832.432自底向上0.1040.1040.1070.1630.743从以上的数据中可以看出递归的使用,对于速度的影响是极大的,特别是数据量足够大的时候,而改进算法减少了递归的调用,也使得速度提升变得极为明显。

0 0