基础排序算法(3)

归并排序

  归并排序主要运用分治法的思想,对待排序列进行排序。分治法的思想主要是将问题规模变小,

逐一求解,从而得到整体的解。

  运用分治法解决问题主要有三个步骤:

  分解(Divide): 将原问题分解为一系列子问题。

  解决 (Conquer): 递归求解子问题,如果子问题足够小,可以直接得到答案;

  合并 (Merge) :将子问题的结果合并成原问题的解。

   归并排序运用分治的思想,可将问题分解为n/k的子问题,n为问题的规模,k为划分的大小。一般取k=2,也称二路归并。

二路归并按照分治法的步骤:先将n个元素划分为n/2的子序列。在递归对子序列进行排序。最后合并两个子序列的结果。如下:

                   n

               n/2            n/2

             n/4       n/4   n/4     n/4

                                       ....      ....     ...        ..     ..      ...

                                   1 . .............................................    1                                           问题规模为1,不用排序,与相邻元素比较合并成上一层的子序列。

 可以通过递归树来对二路归并算法有直观的了解。

时间复杂度:划分子问题的时间为log2 N,排序时间为N,总的时间复杂度为nlog2 n。

java实现:

    public class Merge_Sort{

       public static void main(String[] args){

          int[] unsorted = new int[]{3,2,5,1,7};

          MergeSort(unsorted,0,unsorted.length-1);

          for(int num:unsorted){

            System.out.print("排序后:"+num+" ");

       }

       //归并排序函数Divide && Conquer 步骤1,2

       private static void MergeSort(int unsorted[],int p,int r){

            if(p<r){

              int q = (p+r)/2;

              MergeSort(unsorted,p,q);//递归调用,划分子问题

              MergeSort(unsorted,q+1,r);

              Merge(unsorted,p,q,r); //合并

            }

       }  

       //合并函数Merge 步骤3

       private static void Merge(int unsorted[],int p,int q, int r){

         int n1 = q-p+1; //q为待排数组中值,p为待排数组头,r为待排数组尾 p<=q<=r

         int n2 = r-q;

         int[] left = new int[n1+1];//待合并的左子序列,这里采用二路归并

         int[] right = new int[n2+1];//右子序列;

         for(int i = 0; i < n1;i++){

            left[i] = unsorted[p+i-1];//左子序列为待排序列的前半部分

         }

         for(int j = 0; j < n2;j++){

                                           right[j] = unsorted[q+j];

         }

         left[n1+1] = Integer.Max_Value;//设置哨兵位;

         right[n2+1] = Integer.Max_Value;

         int i = 0;

         int j = 0;

         for(int k = p; p < r;k++){

                                         if(left[i] <= right[j]){

                                          unsorted[k] = left[i];

             i = i+1;

            }else{

                unsorted[k] = right[j];

             j = j+1;

           }

        }

 

    } 

 

posted @ 2019-08-28 14:19  binhuang01  阅读(127)  评论(0编辑  收藏  举报