排序算法之七--归并排序

       还记得学习c语言的时候,老师让你们写的小程序吗。给你两个从小到大的有序数组,然后将这两个数组合并成

一个从小到大的有序数组,归并排序主要就是运用了这种思想。

       你可以想象将这个序列的每个元素先变成一个完全二叉树的叶子点,然后叶子点和叶子点比较形成有序序列,然

后有序序列和有序序列比较形成大的有序序列,最后序列的所有元素都加入进来,形成一个最终的有序序列


示例演示:


                                                  1,2,4,4,5,7,9

                          1,2,4,9                                         4,5,7

             2,4                       1,9                        4,5                 7

         2        4                 1       9                  5      4               7

由上面的演示可以看出,归并排序是一个稳定的排序 ,那么归并排序的算法时间复杂度也可以大概的猜一下呢,二叉树,深度,哈哈,是不是有什么感觉



算法步骤:

1.不断地分解序列,每次都折半划分,直到划分到每一个子序列只有一个元素为止

2.不断地将划分的子序列量量合并后排序

3.返回排序好的序列



算法c语言实现:


#include <stdlib.h>
#include <stdio.h>
 
void  Merge( int  sourceArr[], int  tempArr[],  int  startIndex,  int  midIndex,  int  endIndex)
{
     int  i = startIndex, j=midIndex+1, k = startIndex;
     while (i!=midIndex+1 && j!=endIndex+1)
     {
         if (sourceArr[i] >= sourceArr[j])
             tempArr[k++] = sourceArr[j++];
         else
             tempArr[k++] = sourceArr[i++];
     }
     while (i != midIndex+1)
         tempArr[k++] = sourceArr[i++];
     while (j != endIndex+1)
         tempArr[k++] = sourceArr[j++];
     for (i=startIndex; i<=endIndex; i++)
         sourceArr[i] = tempArr[i];
}
 
//内部使用递归
void  MergeSort( int  sourceArr[],  int  tempArr[],  int  startIndex,  int  endIndex)
{
     int  midIndex;
     if (startIndex < endIndex)
     {
         midIndex = (startIndex + endIndex) / 2;
         MergeSort(sourceArr, tempArr, startIndex, midIndex);
         MergeSort(sourceArr, tempArr, midIndex+1, endIndex);
         Merge(sourceArr, tempArr, startIndex, midIndex, endIndex);
     }
}
 
int  main( int  argc,  char  * argv[])
{
     int  a[8] = {50, 10, 20, 30, 70, 40, 80, 60};
     int  i, b[8];
     MergeSort(a, b, 0, 7);
     for (i=0; i<8; i++)
         printf ( "%d " , a[i]);
     printf ( "\n" );
     return  0;
}

(来源百度百科)


时间复杂度:开始的时候说了,可以想象为一颗递归完全二叉树,自叶子节点向根节点构建,高度为log2n,每一层的总比较次数为N

空间复杂度:在任何时刻只需要一个临时数组即可,该数组任意部分都可以被使用,这样的话,O(n)即可

稳定性:上面分析过了,稳定。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值