MERGE_SORT(归并排序)--算法导论

归并排序的主要思想为分治法,分治模式在每层递归时都有三个步骤:

1.分解原问题为若干子问题,这些子问题是原问题的规模较小的实例。

2.解决这些子问题,递归地求解各个子问题。然而,若递归问题规模足够小,则直接求解。

3.合并这些子问题的解成原问题的解。

归并排序算法完全遵循分治模式。直观上其操作如下:

分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。

解决:使用归并排序递归两个子序列。

合并:合并两个已排序的子序列以产生已排序的答案。

咱先整个数组:

假设一数组A,p,q,r为数组下标,p为靠左边的下标,q为中间下标,r为靠右边的下标

为了简化代码,我们引入了哨兵位\infty(此代替了很大很大的数),解决了:有一边数组合并完了,另外一边还有一些元素,此时需要将这些元素都接到排序好的数组后面。有哨兵位只需要继续和哨兵位(很大很大的数)比较,此时永远比其小,则可接着后面排,这样就不用判断哪边数组先为空。

排序合并的伪代码如下:

MERGE(A , p , q , r )

        n1 =  q - p + 1                                          //n1为左边的元素个数包括q下标的元素

        n2 = r - q                                                 //n2 为右边的元素个数

        let L[0...n1] and R [0...n2] be new arrays   //新建一个左数组打小为(n1+1),和右数组大(n2+1)

        for i = 0 to n1-1                                           //循环将左边元素放进左数组 L 中

                L[i] = A[p + i - 1]

        for j=0 to n2-1                                            //循环将右边元素放进右数组 R 中

                R[ j ] = A[ q+j ]

        L [n1] = \infty                                                //在数组 L 和 R的最后下标位置设置哨兵\infty 

        R[n2] = \infty

        i = 0                                                         //将 i,j 设为 0准备开始合并

        j = 0

        for k=p to r                   //定义变量k为下标p循环直到下标r,排序的元素全部进入数组A停止

                if L[i] <= R[j]            //小的元素先进入,假设L先排完,循环不停止,R要排的元素和-

                        A[k] = L[i]        // L的哨兵(\infty)比较,继续向A中排,直到需要排的元素排完,-

                        i = i+1               //因为有p到r的元素个数限制,哨兵是不会进入数组A中。

                else 

                        A[k] = R[j]

                        j = j+1

     直接看栗子:

根据上图的归并排序可知,相同的元素 2 (绿色和蓝色),在排完序后相对位置没有发生改变,左边的2依旧在左边,右边的2依旧在右边。所以归并排序是稳定的

合并的过程我们大致已经理解了,现在只需要将数组分解就可,由于合并操作必须是两组有序的数组,我们通过二分将原数组一直分割,分割成只有一个元素,分解的过程可使用递归和非递归两种方式。

递归的伪代码:

MERGE-SORT(A,p,r)

        if p < r

                q = (p + r) / 2

                MERGE-SORT(A,p,q)

                MERGE-SORT(A,q+1,r)

                MERGE(A,p,q,r)

如下是递归一边的分解图,由于空间不够,另一半交给你们自己了

归并总图如下:

归并排序算法分析

该算法时间的主要消耗来自于合并算法,我们这里只考虑合并算法的消耗

根据合并算法(MERGE())可知该算法消耗的时间传入的数组的元素个数有关,我们假设一个元素所要消耗的时间为 C,共有n个元素,令n为2的幂这样方便计算。

递归树:

如图可知,树的高度h为:2^{h-1}=n \rightarrow \log_{2}n=h-1\rightarrow h= \log_{2}n+1

如图每一高度层都有n个元素进行MERGE归并操作,每层消耗时间都为C*n

由于最后一层都为一个元素,不需要MERGE操作,我们假定不消耗时间

综上可粗略得到消耗的时间为T(n)=(h-1)*C*n=C*n*\log_{2}n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值