归并排序(非递归)
这次自己写了一下
总结起来就是:
归并排序递归和非递归形式是逆过程。
两者有的地方是一样的,不一样的地方是:
递归是递归拆分成一小段一小段的排序,同时是把A拆成A1 A2,先把A1整个排好,再排A2,最后达到排好整个A的目的。
非递归是序列从左往右先按等分的长度(i)逐个排好,长度不够i的在末尾,于是对它排一次序,然后让i两倍递增。
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX 1000 #define OK 1 #define ERROR 0 using namespace std; typedef struct { int t[MAX]; int a[MAX]; int length; }ma; void LoadList(ma &m) { int i; for(i=0;i<m.length;i++) printf("%d ",m.t[i]); printf("\n"); } void merge(ma &m,int x,int y,int mid) { int i,p,q; p=x,q=mid,i=x; while(p<mid || q<y) { if(q>=y || (p<mid && m.t[p]<=m.t[q])) m.a[i++]=m.t[p++]; else m.a[i++]=m.t[q++]; } for(i=x;i<y;i++) m.t[i]=m.a[i]; } void merge_sort(ma &m) { int p,i; i=2; while(i<m.length) { p=0; while(p+i<m.length) { merge(m,p,p+i,(p+i/2)); p+=i; } merge(m,p,m.length,(p+m.length)/2); i*=2; LoadList(m); } merge(m,0,m.length,i/2); //排列后面还没有加入整个序列的i/2元素(第i/2号元素~m.length-1号元素) LoadList(m); } int main() { int i; ma m; scanf("%d",&m.length); memset(m.a,0,sizeof(m.a)); for(i=0;i<m.length;i++) { scanf("%d",&m.t[i]); } merge_sort(m); return 0; } /* 10 5 4 8 0 9 3 2 6 7 1 4 5 0 8 3 9 2 6 1 7 0 4 5 8 2 3 6 9 1 7 0 2 3 4 5 6 8 9 1 7 0 1 2 3 4 5 6 7 8 9 */