迭代法实现归并排序

来源:互联网 发布:java swing图形界面 编辑:程序博客网 时间:2024/06/13 08:59

归并排序往往以递归的形式实现,如果面试官要求你实现一个迭代版本,又该如何实现呢?

首先给出常见的递归版本:

<span style="font-family:Times New Roman;font-size:14px;">static void merge(int a[], int left, int mid, int right, int temp[]){   int i = left, j = mid+1, k = 0;   while(i <= mid && j <= right)   {   if(a[i] <= a[j])   temp[k++] = a[i++];   else   temp[k++] = a[j++];   }   while(i <= mid)   temp[k++] = a[i++];   while(j <= right)   temp[k++] = a[j++];   for(int idx = 0; idx < k; idx++)   a[idx+left] = temp[idx];}static void mergeSort2(int ar[], int left, int right, int temp[]){if(left < right){int mid = (right - left)/2 + left;mergeSort2(ar, left, mid, temp);mergeSort2(ar, mid+1, right, temp);merge(ar, left, mid, right, temp);}}void mergeSortRecur(int a[], int len){int *temp = (int *)malloc(sizeof(int)*len);mergeSort2(a, 0, len-1, temp);}</span>

其原理不再详细阐述,下面给出迭代版本(其中merge函数和递归版本的一样),参考自点击打开链接,附带部分注释:

<span style="font-family:Times New Roman;font-size:14px;">static void mergePass(int a[], int temp[], int s, int n){int i = 0;while(i < n - 2 * s){merge(a, i , i+s-1, i + 2 * s -1, temp);//Merge two adjacent segments of size si = i + 2 * s;} // fewer than 2s elements remain//possible 1,(s, 2s) leftif(i + s < n)merge(a,  i, i + s-1, n-1, temp);else   //possible 2, (0, 2)leftfor(int j = i; j <= n-1; j++)temp[j] = a[j];}void mergeSortItera(int a[], int len){int *temp = (int *)malloc(sizeof(int)*len);int start = 1;while(start  < len){mergePass(a, temp, start, len);start += start;        /*mergePass(temp, a, start, len);start += start;*/}}</span>
可以看出,迭代版的归并排序依然需要O(n)的额外空间,其首先设置步长为1,然后逐步加倍,完成归排序过程。边界条件是,在某个步长处,可能存在不能等分的情况,此时需要视情况而定。设步长为s,则不外乎如下两种情况:1、剩下的元素个数为(s, 2*s),2、剩下的元素个数为(0, s)。前者可以再次归并,后者按照元素原来的顺序拷贝回去就可以了。

0 0
原创粉丝点击