归并排序
来源:互联网 发布:专业铃声制作软件 编辑:程序博客网 时间:2024/05/16 14:08
归并排序
归并排序是将一个序列逐次对半分组直到数组元素为1,然后逐次两两合并分组直至成一个序列。
在逐次两两合并分组时需要一个临时的buffer。
参考百度百科:http://baike.baidu.com/link?url=OD11jIUEKqkbhY9w0loP9FFlLipaxfq6WkBZo1_O9MMuGMcn3h3rqWoZ0l7hMDKJOQrDlVPf9ELLsLijxSHs6ZapL-BMVl6k9ZEQIIyLOvVXVhm-gQEg9Y_TYwPZGFTZ
递归调用
归并排序的递归调用c代码如下:
void MergePartition_Recursion (int * const piSrc, const int start, const int mid, const int end, int * const piTemp){ int i = start; int iEnd = mid; int j = mid + 1; int jEnd = end; int k = 0; while (i<=iEnd && j<=jEnd) { if (piSrc[i] > piSrc[j]) piTemp [k++] = piSrc [j++]; else piTemp [k++] = piSrc [i++]; } while (i <= iEnd) piTemp [k++] = piSrc [i++]; while (j <= jEnd) piTemp [k++] = piSrc [j++]; i = 0; while (i < k) { piSrc [i+start] = piTemp [i]; i ++; }}void MergeSort_Recursion (int * const pia, const int start, const int end, int * const piTemp){ int mid; if (start < end) { mid = (start + end) >> 1; MergeSort_Recursion(pia, start, mid, piTemp); MergeSort_Recursion(pia, mid+1, end, piTemp); MergePartition_Recursion (pia, start, mid, end, piTemp); }}
注释:
1. 代码中用到了递归;
2. 在MergePartition_Recursion中将合并数据拷贝到piSrc时,下标是从start开始的;
c完整代码:
#include <stdio.h>#include <stdlib.h>#include<windows.h>void MergePartition_Recursion (int * const piSrc, const int start, const int mid, const int end, int * const piTemp){ int i = start; int iEnd = mid; int j = mid + 1; int jEnd = end; int k = 0; while (i<=iEnd && j<=jEnd) { if (piSrc[i] > piSrc[j]) piTemp [k++] = piSrc [j++]; else piTemp [k++] = piSrc [i++]; } while (i <= iEnd) piTemp [k++] = piSrc [i++]; while (j <= jEnd) piTemp [k++] = piSrc [j++]; i = 0; while (i < k) { piSrc [i+start] = piTemp [i]; i ++; }}void MergeSort_Recursion (int * const pia, const int start, const int end, int * const piTemp){ int mid; if (start < end) { mid = (start + end) >> 1; MergeSort_Recursion(pia, start, mid, piTemp); MergeSort_Recursion(pia, mid+1, end, piTemp); MergePartition_Recursion (pia, start, mid, end, piTemp); }}int testArray[] = {1,3,5,7,9,2,4,6,8,0, 54, 48, 2 , 5 , 8};//{5,5,5,5,5,5,5,5,5,5,5};//void PrintfIntArray (int * const pia, const int n){ int i; for (i=0; i<n; i++) printf("%u ", pia[i]); printf("\n");}int main(){ DWORD startTime; DWORD endTime; int aiTemp[sizeof(testArray)/sizeof(testArray[0])]; printf("Hello world!\n"); startTime = GetTickCount (); MergeSort_Recursion (testArray, 0, sizeof(testArray)/sizeof(int)-1, aiTemp); endTime = GetTickCount(); printf ("Sort Time Consumption:%lu ms.\n", endTime-startTime); PrintfIntArray (testArray, sizeof(testArray)/sizeof(int)); return 0;}
非递归调用
归并排序的递归调用,对栈的消耗还是不小的。根据《大话数据结构》P413页所述,递归深度为log2n,总空间复杂度为O(n+logn)。
参考此书,贴出非递归时的c代码如下:
基本思想是,从底向上两两合并,最开始是一个一个合并,逐次以2的整次幂合并。
递归中MergePartition_Recursion函数中的k是0开始的,因为piTemp在函数MergePartition_Recursion中仅仅作为临时变量。
非递归中的MergePartition_Iteration函数中的k是从startIndex开始,因为piDest保存的内容没有拷贝到piSrc中。因此,在MergeSort_Iteration函数中piTemp和piSrc交替位置传参。
void MergePartition_Iteration (int * const piDest, const int startIndex, const int midIndex, const int endIndex, int * const piSrc){ int i = startIndex; int iEnd = midIndex; int j = iEnd + 1; int jEnd = endIndex; int k = startIndex; while (i<=iEnd && j<=jEnd) { if (piSrc[i] > piSrc[j]) piDest[k++] = piSrc[j++]; else piDest[k++] = piSrc[i++]; } while (i <= iEnd) piDest[k++] = piSrc[i++]; while (j <= jEnd) piDest[k++] = piSrc[j++];}void MergeSort_SplitPartition (int * const piDest, const int splitNum, int * const piSrc, const int len){ int startIndex = 0; if (NULL!=piDest && NULL!=piSrc) { if (splitNum) { while (startIndex < len-2*splitNum+1) { MergePartition_Iteration (piDest, startIndex, startIndex+splitNum-1, startIndex+2*splitNum-1, piSrc); startIndex += 2*splitNum; } if (startIndex < len-splitNum) MergePartition_Iteration (piDest, startIndex, startIndex+splitNum-1, len-1, piSrc); else while (startIndex < len) { piDest[startIndex] = piSrc[startIndex]; startIndex ++; } } }}void MergeSort_Iteration (int * const piSrc, const int len, int * const piTemp){ int splitNum = 1; while (splitNum < len) { MergeSort_SplitPartition (piTemp, splitNum, piSrc, len); splitNum <<= 1; MergeSort_SplitPartition (piSrc, splitNum, piTemp, len); splitNum <<= 1; }}
0 0
- 归并排序-归并排序
- 归并和归并排序
- 归并与归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 排序::归并
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- java 反转字符串(最简单的)
- POJ 1840 Eqs (哈希)
- tanjan算法求强联通分量
- 292. Nim Game
- Stanford POS tagger FAQ
- 归并排序
- Linux下python调用C++接口实现图片及文件的AES加解密
- 树的基本操作
- java基础—内存结构
- 9-10 标准IO之gets,puts,fprintf,sprintf,fgetc,fputc
- 《阳光灿烂的日子》
- RefineNet: Multi-Path Refinement Networks for High-Resolution Semantic Segmentation
- 父子窗口之间的通信
- java类型自动转换和信息丢失情况