自底向上的归并排序 .[转]

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

原文链接:http://blog.csdn.net/cjf_iceking/article/details/7920153

 

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

 一. 算法描述

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

 二、算法分析

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

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

排序稳定性:稳定

三、算法实现

 1 /********************************************************
 2 *函数名称:Merge
 3 *参数说明:pDataArray 无序数组;
 4 *          int *pTempArray 临时存储合并后的序列
 5 *          bIndex 需要合并的序列1的起始位置
 6 *          mIndex 需要合并的序列1的结束位置
 7                   并且作为序列2的起始位置
 8 *          eIndex 需要合并的序列2的结束位置
 9 *说明:    将数组中连续的两个子序列合并为一个有序序列
10 *********************************************************/
11 void Merge(int* pDataArray, int *pTempArray, int bIndex, int mIndex, int eIndex)
12 {
13     int mLength = eIndex - bIndex;    //合并后的序列长度
14     int i = 0;    //记录合并后序列插入数据的偏移
15     int j = bIndex;    //记录子序列1插入数据的偏移
16     int k = mIndex;    //记录子序列2掺入数据的偏移
17 
18     while (j < mIndex && k < eIndex)
19     {
20         if (pDataArray[j] <= pDataArray[k])
21         {
22             pTempArray[i++] = pDataArray[j];
23             j++;
24         }
25         else
26         {
27             pTempArray[i++] = pDataArray[k];
28             k++;
29         }
30     }
31 
32     if (j == mIndex)    //说明序列1已经插入完毕
33         while (k < eIndex)
34             pTempArray[i++] = pDataArray[k++];
35     else                //说明序列2已经插入完毕
36         while (j < mIndex)
37             pTempArray[i++] = pDataArray[j++];
38 
39     for (i = 0; i < mLength; i++)    //将合并后序列重新放入pDataArray
40         pDataArray[bIndex + i] = pTempArray[i];
41 }
42 
43 /********************************************************
44 *函数名称:BottomUpMergeSort
45 *参数说明:pDataArray 无序数组;
46 *           iDataNum为无序数据个数
47 *说明:    自底向上的归并排序
48 *********************************************************/
49 void BottomUpMergeSort(int* pDataArray, int iDataNum)
50 {
51     int *pTempArray = (int *)malloc(sizeof(int) * iDataNum);    //临时存放合并后的序列
52     int length = 1;    //初始有序子序列长度为1
53     while (length < iDataNum)
54     {
55         int i = 0;
56         for (; i + 2*length < iDataNum; i += 2*length)
57             Merge(pDataArray, pTempArray, i, i + length, i + 2*length);
58         if (i + length < iDataNum)
59             Merge(pDataArray, pTempArray, i, i + length, iDataNum);
60         length *= 2;    //有序子序列长度*2
61     }
62     free(pTempArray);
63 }
View Code

 

 

相关文章
|
6月前
|
人工智能 算法
【算法分析与设计】递归与分治策略(二)
【算法分析与设计】递归与分治策略
|
6月前
|
机器学习/深度学习 算法 编译器
【算法分析与设计】递归与分治策略(一)
【算法分析与设计】递归与分治策略
|
算法 搜索推荐
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
|
6月前
|
算法
算法分析与设计——递归算法(二)1.汉罗塔问题
算法分析与设计——递归算法(二)1.汉罗塔问题
|
6月前
|
算法
算法分析与设计——递归算法(一)
算法分析与设计——递归算法(一)
|
6月前
|
算法 搜索推荐 Windows
【算法分析与设计】递归与分治策略(三)
【算法分析与设计】递归与分治策略
|
10月前
|
算法
初学算法之分治---快速排序
初学算法之分治---快速排序
|
10月前
|
机器学习/深度学习 存储 分布式计算
算法思想--分治算法
分治算法是一种常见的算法思想,其基本思想是将一个大问题分解成若干个小问题,然后通过递归的方式解决每个小问题,最后将所有小问题的解合并起来得到大问题的解。分治算法通常包含三个步骤:分解、解决和合并....
83 0
算法思想--分治算法
|
10月前
|
算法
初学算法之分治---求逆序数
初学算法之分治---求逆序数
|
11月前
P1967 货车运输 Kruskal重构树
P1967 货车运输 Kruskal重构树
58 0

热门文章

最新文章