归并排序详解——思路分析以及核心代码(java)实现...非递归实现

来源:互联网 发布:订货单软件 编辑:程序博客网 时间:2024/05/16 16:02

什么是归并排序?
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。(来自百度,其实这里看不看也行…)


嗯,下面才是正文。

如何对一组数进行归并排序…

先假设那组数是 { 3 , 2 , 4 , 1 , 5 , 9 , 6 }

还有几个要点..
  • 单独的一个数具有 有序性
  • 归并排序的执行步骤为拆分,然后合并。
  • 归并排序的核心是将两个有序数组合并为一个有序数组。

思路分析

一,使用分治策略不断拆分得到有序数组。

拆分的顺序:

  1. { 3 , 2 , 4 , 1 } , { 5 , 9 , 6 }
  2. { 3 , 2 } , { 4 , 1 } , { 5 , 9 } , { 6 }
  3. { 3 } , { 2 } , { 4 } , { 1 } , { 5 } , { 9 } , { 6 }

二,将两个有序数组合并为一个有序数组。

    因为单独的一个数可以看作为有序的.所以在拆分到第三步的时候,每个数组只有一个数,也就是说它们都是有序数组。

然后,用A和B分别表示两个待合并的有序数组。

待合并的有序数组 A = { 3 } B = { 2 }

显然,这里我们可以直接对比两个数的大小,得出一个有序数组{ 2 , 3 }。

下一步,我们再将 { 4 } 和 { 1 } 合并,得出 { 1 , 4 },再将 { 2 , 3 }和{ 1 , 4 }进行合并..

这里需要定义几个变量…

  • int a :用于标记数组A中的数.
  • int b :用于标记数组B中的数.
  • int[] t :一个新的数组,用于数组合并,其长度为 数组A的长度与数组B的长度的和..
a=0;b=0 a=0;b=1; a=1;b=1; a=2;b=1; A={ 2 , 3 } A={ 2,3 } A={3} A={} B={ 1 , 4 } B={4} B={4} B={4} A[a] > B[b] A[a] < B[b] A[a] < B[b] A为空数组 t[0]=B[b],b++ t[1] = A[a],a++ t[2] = A[a],a++ t[3] = B[b],b++
/*这是用于合并数组的代码..   isEmpty方法返回一个数组是否为空.. */for( int index = 0 ; index<t.length ; index++ )    if( isEmpty(A) || ( !isEmpty(B) && A[a]>B[b] )         t[index] = B[b++];    else        t[index] = A[a++];

唔,然后我随手画了一张总流程图….用于观察..

归并排序流程图

要相信,这图是有意义的。

我们可以观察到,在合并的时候,才会发生数的交换,所以根据此特性,我们可以忽略拆分的步骤,直接进行合并操作。

这里写图片描述

下面是核心代码…这是我第三次优化后的实现…我认为比网上的代码都要优美和直观多了….

/*    Nums为需要进行排序的数组.. */private void sort(){        for(int i = 1 ; i<Nums.length ; i*=2){            for(int j = 0 ; j<Nums.length ; j+=(i*2) ){                //如果i+j>Nums.length,那么就不需要执行,因为已经是有序。                //关于这里为什么是有序的,我觉得值得大家去思考。                if(i+j < Nums.length){                    if( 2*i+j > Nums.length )                        merge(j,j+i,Nums.length-j);                    else                        merge(j,j+i,2*i);                }            }        }    }    private void merge(int a,int b,int size){        int N = a;//标记数组t在原数组Nums的位置,        int A_Length = b;//标记数组A的长度        int B_length = a+size;//标记数组B的长度        int[] t = new int[size];//创建数组t来构建有序数组..        for(int index = 0; index < size ;index++)            if( a == A_Length || ( b != B_length  && Nums[a]>Nums[b] ) ){                t[index] = Nums[b++];            }else{                t[index] = Nums[a++];            }        for(int i = 0;i<t.length;i++){            Nums[N++] = t[i];         }    }
0 0
原创粉丝点击