首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

自底向下的归并排序

2012-09-15 
自底向上的归并排序今日翻开严蔚敏的《数据结构(C语言版)》感慨一二,首先书中讲解之详细与形象乃本人博文所

自底向上的归并排序

    今日翻开严蔚敏的《数据结构(C语言版)》感慨一二,首先书中讲解之详细与形象乃本人博文所不能比拟,有这么一句话说的好"所有的答案都在书中,只是你学习的时候没有注意罢了";其次书的第一章里提到算法的设计要求,除了效率健壮性等,可读性也是重要的一部分,让楼主想起了昨天所写的插入排序中,从后向前查找的代码就比从前向后查找的代码可读性高,这样代码出错的概率降低 和 他人阅读的效率提升;再次,感慨留到下一次再说吧......切入主题----自底向上的归并排序。

一. 算法描述

    自底向上的归并排序:归并排序主要是完成将若干个有序子序列合并成一个完整的有序子序列;自底向上的排序是归并排序的一种实现方式,将一个无序的N长数组切个成N个有序子序列,然后再两两合并,然后再将合并后的N/2(或者N/2 + 1)个子序列继续进行两两合并,以此类推得到一个完整的有序数组。下图详细的分解了自底向上的合并算法的实现过程:

自底向下的归并排序

二. 算法分析

平均时间复杂度:O(nlog2n)

空间复杂度:O(n)  (用于存储有序子序列合并后有序序列)

稳定性:稳定

三. 算法实现
/*********************************************************函数名称:Merge*参数说明:pDataArray 无序数组;*          bIndex 需要合并的序列1的起始位置*          mIndex 需要合并的序列1的结束位置                  并且作为序列2的起始位置*          eIndex 需要合并的序列2的结束位置*说明:    将数组中连续的两个子序列合并为一个有序序列*********************************************************/void Merge(int* pDataArray, int bIndex, int mIndex, int eIndex){int mLength = eIndex - bIndex;    //合并后的序列长度int *pTempArray = (int *)malloc(sizeof(int) * mLength);    //临时存储合并后的序列int i = 0;    //记录合并后序列插入数据的偏移int j = bIndex;    //记录子序列1插入数据的偏移int k = mIndex;    //记录子序列2掺入数据的偏移while (j < mIndex && k < eIndex){if (pDataArray[j] <= pDataArray[k]){pTempArray[i++] = pDataArray[j];j++;}else{pTempArray[i++] = pDataArray[k];k++;}}if (j == mIndex)    //说明序列1已经插入完毕while (k < eIndex)pTempArray[i++] = pDataArray[k++];else                //说明序列2已经插入完毕while (j < mIndex)pTempArray[i++] = pDataArray[j++];for (i = 0; i < mLength; i++)    //将合并后序列重新放入pDataArraypDataArray[bIndex + i] = pTempArray[i];free(pTempArray);}/*********************************************************函数名称:BottomUpMergeSort*参数说明:pDataArray 无序数组;*   iDataNum为无序数据个数*说明:    自底向上的归并排序*********************************************************/void BottomUpMergeSort(int* pDataArray, int iDataNum){int length = 1;    //初始有序子序列长度为1while (length < iDataNum){int i = 0;for (; i + 2*length < iDataNum; i += 2*length)Merge(pDataArray, i, i + length, i + 2*length);if (i + length < iDataNum)Merge(pDataArray, i, i + length, i + iDataNum);length *= 2;    //有序子序列长度*2}}


1楼hello0406昨天 21:04
刚看了西昆仑的二茶树,再来瞧瞧楼主的归并!
Re: CJF_iceKing昨天 21:46
[quote=hello0406]刚看了西昆仑的二茶树,再来瞧瞧楼主的归并![/quote]n呵呵~~~ 我在打基础呢~~~

热点排行