看图说话排序算法之归并排序

    归并排序和快速排序类似,都典型以递归方式实现的算法,归并排序的时间复杂度分析也和快速排序的时间复杂度分析类似。本文主要介绍归并排序算法基本原理,定性分析归并排序的时间复杂度以及给出java代码实现。

一丶归并排序算法基本原理
    在介绍归并排序算法之间,需要分析一个特殊排序的例子——假设存在数组A和数组B,A和B都是顺序排序的,现在需要将这两个顺序排序的数组进行合并得到数组C,并且保证合并后数组有序。

int [] A = new int[]{4,5,6,10,12,17};

int [] B = newint[]{1,3,8,9,15,20,32,50};

    由于数组A和数组B都是排序数组,所以合并这两个数组,并且保持有序是可以在线性时间完成的,上述的合并排序过程用代码描述如下:

                 int indexA = 0;
                 int indexB=0;
                 int [] C = new int[indexA.length+B.length];
                 int indexC=0;
                 while(indexA<A.length&&indexB<B.length){
                      if(A[indexA]<B[indexB]){
                            C[indexC++]= A[indexA++];
                      }else{
                           C[indexC++] =B[indexB++];
                      }
                 while(indexA<A.length){
                      C[indexC++]=A[indexA++];
                }
                while(indexB<B.length){
                      C[indexC++] = B[indexB++];
                }
             }

    通过分析上述代码的实现过程,只要数组A和数组B是排序数组,那么在线性时间内可以完成两个数组的合并,并且保证。

    如果理解了上述排序的过程的话,其实对归并排序的理解已经完成了一大部分了,上述排序的过程就是归并排序算法中的核心,假面我们通过一个例子来观察归并排序的实现过程。假设待排序数组A满足:

int[] A= new int[]{4,5,3,2,1,8,7};
图1 归并排序细分数组
  1. 图1所示代表对待排序数组进行细分的结构,上述细分结构非常有讲究,在图1中最低层的元素都是单个元素为一组,单个元素也可以看成一个排序数组。那么对同一个父节点下的两个排序数组进行上文中描述的合并操作就可以完成阶段性的排序,合并的结果如下:
图 2 第一步归并排序
  1. 图2中显示了对细分数组的最底层进行的合并操作结果,通过上述合并操作后,不难发现,倒数第二层每个细分数组都满足顺序性了,所以接着对倒数第二层细分数组重复步骤1中的合并操作,结果如下图所示。


    图3 第二步归并排序
  2. 图3中显示了对细分数组的倒数第二层进行合并操作结果,通过上述合并操作后发现,到处第三层的每个细分数组都满足顺序性了,同理重复步骤1中的合并操作,完成对整个数组的排序。


    图4第三步归并排序

    上述三个步骤就是利用归并排序对数组进行排序的过程,从上述分析角度可以看出归并排序是一个明显的递归排序算法,其核心操作是对两个顺序的子数组进行合并操作。

二丶归并排序算法的时间复杂度分析

  1. 定性的分析归并排序的时间复杂度:长度为N的待排序数组,依据上文中的细分结构,最多能被分成Log(N)层。每层的子数组都会进行合并操作,每层比较的总次数都是N。所以时间复杂是Nlog(N)。

  2. 定量分析归并排序的时间复杂度:归并排序的时间复杂度分析是典型的递归时间复杂度分析的例程,这里用简单的篇幅描述一下定量分析递归算法时间复杂度的过程。

将对长度为N的数组进行递归排序的时间消耗记T(N),同时假设N是偶数。那么依据递归排序的过程T(N)可如下计算:

T(N)=2T(N/2)+N                              (1)

方程两边同时除以N,得到下式:

T(N))/N=T(N/2)/(N/2)+1                    (2)

 对于式2而言,利用N=依次带入可得:

T(N/2))/(N/2)=T(N/4)/(N/4)+1              (3)

T(N/4))/(N/4)=T(N/8)/(N/8)+1               (4)

                                                                     ⋮

T(2))/2=T(1)/1+1(LogN+3)   (LogN+1)

将式(2)到式(LogN+1)依次相加起来,可得:

T(N))/N=T(1)/1+logN                   (LogN+2)

(N)=N+NlogN=O(NlogN)              (LogN+3) 

通过上述计算可以清晰的看到归并排序的时间复杂度分析过程。

三丶归并排序的java代码实现

public class Solution {
    /*
     * @param A:an integer array
     * @return:
     */
    public voidsortIntegers2(int[] A) {
        // writeyour code here
        //利用归并排序对数组A进行排序
       mergeSort(A,0,A.length-1);
    }
    //归并排序
    public void mergeSort(int[] A,int start,int end){
       if(start>=end) return;
        int middle= (start+end)/2;
       mergeSort(A,start,middle);
       mergeSort(A,middle+1,end);
        //归并排序需要分配的临时数组
        //这是归并排序的核心
        int []temp  = new int[end-start+1];
        inti=start;
        int j =middle+1;
        intindex=0;
       while(i<=middle&&j<=end){
           if(A[i]<=A[j]){
               temp[index++] = A[i++];
            }else{
               temp[index++] = A[j++];
            }
        }
       while(i<=middle){
           temp[index++] =A[i++];
        }
       while(j<=end){
           temp[index++] =A[j++];
        }
        i=start;
        index = 0;
       for(;i<=end;i++){
            A[i] =temp[index++];
        }
    }
}

Reference:
[1] 数据结构与算法java语言描述版
[2]原文博客博客链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355