zoukankan      html  css  js  c++  java
  • 归并排序

    归并排序

    二分,比较与合并。

    原理

    采用递归和分治的思想,首先将数组二分成多个子序列,然后两两子序列进行比较与合并,使其合并为一个完全有序的序列。不断进行比较与合并,使子序列们最终合并为一个完整有序的序列。

    分析

    最佳:o(n) 
    最坏:o(nlogn) 
    平均:o(nlogn)

    稳定,适用大规模,内存允许。

    详细过程

    当我们要排序这样一个数组的时候,归并排序法首先将这个数组分成一半。如图:

    然后想办法把左边的数组给排序,右边的数组给排序,之后呢再将它们归并起来。当然了当我们对左边的数组和右边的素组进行排序的时候,再分别将左边的数组和右边的数组分成一半,然后对每一个部分先排序,再归并。如图:

    对于上面的每一个部分呢,我们依然是先将他们分半,再归并,如图:

    分到一定细度的时候,每一个部分就只有一个元素了,那么我们此时不用排序,对他们进行一次简单的归并就好了。如图:

    归并到上一个层级之后继续归并,归并到更高的层级,如图:

    直至最后归并完成。

    我们可以开辟一个临时数组来辅助我们的归并。也就是说他比我们插入排序也好,选择排序也好多使用了存储的空间,也就是说他需要o(n)的额外空间来完成这个排序。

    整体来讲我们要使用三个索引来在数组内进行追踪。

    蓝色的箭头表示最终选择的位置,而红色的箭头表示两个数组当前要比较的元素,比如当前是2与1比较,1比2小,所以1放到蓝色的箭头中,蓝色的箭头后移,1的箭头后移。

    然后2与4比较,2比4小那么2到蓝色的箭头中,蓝色箭头后移,2后移,继续比较.......

    代码

    将数组二分为多个子序列 ;
    子序列进行排序(注:只有1个元素的序列本身就已经是排序好的序列) ;
    排序好的子序列间进行比较与合并;
    子序列完全合并为一个有序序列;

    int arr[];
    int new_arr[];//辅助空间
    void merge(int left,int right){
        int mid = (left+right)/2;
        int i=left,j=mid+1,k=0;
        while(i<=mid && j<=rihgt){
            if(arr[i]<arr[j]) new_arr[k++]=s[i++];
            else new_arr[k++]=arr[j++];
        }
        while(i<=mid) new_arr[k++] = arr[i++];
        while(j<=right) new_arr[k++]=arr[j++];
        for(i=left,k=0;i<=right;i++,k++) arr[i]=new_arr[k];
    }
    
    void mergesort(int left,int right){
        if(left<right){
            int mid = (left+right)/2;
            mergesort(left,mid);
            mergesort(mid+1,right);
            merg(left,right);
        }
    }
  • 相关阅读:
    CSS3很强大
    Notepad++关闭时自动保留,不弹出提示保存对话框
    数据库中更新或插入表记录
    手动指定网卡优先顺序方法
    在Excel中转换时间戳(timeStamp)
    format z: /p:3 & cipher /w z:abc
    修改eclipse中M2_REPO变量值
    Windows 10 主题的图片位置
    MySQL中 delete from 时提示 1064 错误。
    left join 中 on 与 where 理解
  • 原文地址:https://www.cnblogs.com/pacino12134/p/11177733.html
Copyright © 2011-2022 走看看