归并排序数组实现之递归和非递归方法

来源:互联网 发布:浮云散明月照人来 知乎 编辑:程序博客网 时间:2024/05/04 19:00

参考:http://blog.csdn.net/prstaxy/article/details/8166360

归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的,然后再把有序子序列合并为整体有序序列。

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

时间复杂度为O(nlogn),空间复杂度为 O(n),归并排序比较占用内存,但却效率高且是稳定的算法。


下面的代码是递归和非递归的实现。

#include<iostream>using namespace std;void printArray(int data[],int size);void merge(int data[], int low,int mid, int high) //两个有序子序列合并{//子序列1:数组下标low到mid           //子序列2:数组下标mid+1到high           int *temp=new int[high-low+1];int i=low, j=mid+1, ti=0; //ti:合并后temp数组的下标if(temp==NULL){cout<<"内存分配失败"<<endl;}printf("对下标%d--%d--%d  数字%d--%d排序\n",low,mid,high,data[low],data[high]);while(i<=mid && j<=high){if(data[i]<data[j]){cout<<data[i]<<"<"<<data[j]<<endl;temp[ti++]=data[i++];}else{cout<<data[j]<<"<"<<data[i]<<endl;temp[ti++]=data[j++];}}while(i<=mid) //若序列1还有剩余,将剩余元素放入新数组中temp[ti++]=data[i++];while(j<=high) //若序列2还有剩余,将剩余元素放入新数组中temp[ti++]=data[j++];for(ti=0;ti<high-low+1;ti++) //将排序后的数组元素,放入原数组中相应的位置data[low+ti]=temp[ti];delete[] temp;}
//<span style="color: rgb(54, 46, 43); font-family: Arial; font-size: 14px; line-height: 26px;">递归的合并排序,如果子数组中至多有一个元素,当然是已排好,否则分解</span>void mergeSort(int data[], int low, int high)  //递归实现归并排序{if(low<high) //不少于2个元素,进行合并{int mid=(low+high)/2;mergeSort(data,low,mid);        //拆分左边子序列mergeSort(data,mid+1,high);  //拆分右边子序列merge(data,low,mid,high);  //合并printArray(data,9);}}void mergeSort(int data[], int n) //非递归实现排序,基本思想是:两两合并{int step=1;  //步长2的指数增长1,2,4,8,16....int i;while(step<=n) {int low=0;  //每次对整个数组合并前,low=0;从头开始printf("step=%d\n",step);while(low<=n-1){int mid=low+step-1;int high=mid+step;if(high>=n) //high下标判断high=n-1;if(mid>high) //mid下标判断mid=high;merge(data,low,mid,high);low=high+1;}printArray(data,9);step=step*2;}}void printArray(int data[],int size){int i;for(i=0;i<size;i++)cout<<data[i]<<" ";cout<<endl;}int main(){int data[9]={5,3,6,2,1,9,4,8,7};cout<<"排序前:"<<endl;printArray(data,9);cout<<"排序过程:"<<endl;mergeSort(data,0,8);  //递归//mergeSort(data,9);  //非递归}

递归结果:


排序前:5 3 6 2 1 9 4 8 7排序过程:对下标0--0--1  数字5--3排序3<53 5 6 2 1 9 4 8 7对下标0--1--2  数字3--6排序3<65<63 5 6 2 1 9 4 8 7对下标3--3--4  数字2--1排序1<23 5 6 1 2 9 4 8 7对下标0--2--4  数字3--2排序1<32<31 2 3 5 6 9 4 8 7对下标5--5--6  数字9--4排序4<91 2 3 5 6 4 9 8 7对下标7--7--8  数字8--7排序7<81 2 3 5 6 4 9 7 8对下标5--6--8  数字4--8排序4<77<98<91 2 3 5 6 4 7 8 9对下标0--4--8  数字1--9排序1<42<43<44<55<76<71 2 3 4 5 6 7 8 9请按任意键继续. . .



非递归结果:

排序前:5 3 6 2 1 9 4 8 7排序过程:step=1对下标0--0--1  数字5--3排序3<5对下标2--2--3  数字6--2排序2<6对下标4--4--5  数字1--9排序1<9对下标6--6--7  数字4--8排序4<8对下标8--8--8  数字7--7排序3 5 2 6 1 9 4 8 7step=2对下标0--1--3  数字3--6排序2<33<65<6对下标4--5--7  数字1--8排序1<44<98<9对下标8--8--8  数字7--7排序2 3 5 6 1 4 8 9 7step=4对下标0--3--7  数字2--9排序1<22<43<44<55<86<8对下标8--8--8  数字7--7排序1 2 3 4 5 6 8 9 7step=8对下标0--7--8  数字1--7排序1<72<73<74<75<76<77<81 2 3 4 5 6 7 8 9请按任意键继续. . .


0 0
原创粉丝点击