算法之旅——合并排序

来源:互联网 发布:93国际大专辩论赛网络 编辑:程序博客网 时间:2024/06/07 18:05

合并排序是用分治策略实现对n 个元素进行排序的算法。其基本思想是,将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合合并成所要求的排好序的集合。

其递归描述如下:

#include <iostream>#define N 8typedef int Type;using namespace::std;Type *b = new Type[N];void MergeSort(Type a[], int left, int right);void Merge(Type a[], Type b[], int left, int i, int right );void MergeSort(Type a[], int left, int right){if(left < right){int i = (left + right) / 2;MergeSort(a, left, i);MergeSort(a, i+1, right);Merge(a, b, left,  i, right);  //Merge to array of 'b'}}void Merge(Type a[], Type b[], int left, int i, int right ){int x = left, y = i+1, k = left;while((x <= i) && (y <= right)){if(a[x] < a[y])  b[k++] = a[x++];else b[k++] = a[y++];}while(x <= i) b[k++] = a[x++];while(y <= right) b[k++] = a[y++];for(int i = left; i < k; i++)a[i] = b[i];}int main(){Type a[N] = {4,8,3,7,1,5,6,2};MergeSort(a, 0, 7);for(int i = 0; i < N; i++)cout << a[i] << ',';cout << endl;return 1;}


消去递归的合并算法如下:

#include <iostream>typedef int Type;using namespace::std;void Merge(Type c[], Type d[], int l, int m, int r){int i = l, j = m+1, k = l;while((i <= m) && (j <= r)){if(c[i] <= c[j]) d[k++] = c[i++];else d[k++] = c[j++];}if(i > m) for(int q = j; q <= r;  q++) d[k++] = c[q];else for(int q = i; q <= m; q++) d[k++] = c[q];}void MergePass(Type x[], Type y[], int s, int n){int i = 0;while( i <= n - 2 * s){Merge(x, y, i, i+s-1, i+2*s-1);i = i+2 * s;}if(i + s < n) Merge(x, y, i, i+s-1, n-1);else for(int j = i; j <= n-1; j++) y[j] = x[j];}void MergeSort(Type a[], int n){Type *b = new Type[n];int s = 1;int i = 0;while(s < n){MergePass(a,b,s,n); //合并到数组bs += s;MergePass(b,a,s,n); // 合并到数组as += s;}}int main(){Type num[] = {8,4,7,3,1,5,6,2};MergeSort(num, 8);for(int j = 0; j < 8;  j++)cout << num[j];int i; cin >> i;return 1;}

自然合并排序如下:

#include <iostream>#define N 8typedef int Type ;using namespace::std;void MergeSort_Natural(Type a[], int n);int Scan(Type a[], Type b[], int n);void Merge(Type a[], Type b[], int left , int mid, int right);//自然归并排序void MergeSort_Natural(Type a[], int n){Type *b = new Type[N];while(1){if(Scan(a,b,n) == 0) break;if(Scan(b,a,n) == 0) break;}}/* 线性扫描数列,如果存在逆序的情况就进行合并排序   否则返回一个为零的中间值mid      */ int Scan(Type a[], Type b[], int n){int left = 0, mid = 0, right = n-1;for(int i = 0; i < n-1; i++){// 判断有没有逆序的情况出现 if(a[i] > a[i+1]){// 先设置中间值,后设置右值if(mid == 0)  mid = i;else {right = i;Merge(a, b, left , mid, right);left = right+1;mid = 0;right = n-1;}}}  // 当最后一个组为最后一个数的极端情况if((mid !=0) && (right != 0))Merge(a, b, left , mid, right);return mid;}void Merge(Type a[], Type b[], int left , int mid, int right){int i = left, j = mid+1, k = left;while((i <= mid) && (j <= right)){if(a[i] < a[j]) b[k++] = a[i++];else b[k++] = a[j++];}while(i <= mid) b[k++] = a[i++];while(j <= right) b[k++] = a[j++];}int main(){Type a[N] = {4,8,3,7,1,5,6,2};MergeSort_Natural(a, 8);for(int i = 0; i < N; i++)cout << a[i] << ',';cout << endl;//int i;//cin >> i;return 1;}

合并排序的一个弊端就是额外需要存储器的空间配置,在实际上的实现上,会极度影响速度和高速缓存的性能!

原创粉丝点击