排序算法之归并

来源:互联网 发布:苹果手机关闭移动数据 编辑:程序博客网 时间:2024/04/27 03:35
            归并排序,用到的算法是分治与递归。

        先说下分治。分治,简单来说就是分而治之。将问题一步一步的最小化(递归入)。然后把小问题解决。最后将问题一步一步合并起来(递归出)。

      假设有数组array[] = {2 ,1,8,6,5,4,9,7,3,0}。我们要对它归并排序。

      首先,分!一分二,二变四,四化八,直到就剩一个元素。

      分解步骤:(递归入)

                    1).        {2 1 8 6 5}               {4 9 7 3 0 }

                    2).        {2 1 }   {8 6 5}          {4 9}     {7 3 0}

                    3).        {2} {1} {8}  {6 5}         {4} {9}   {7 3}     {0}

                    4).                         {6} {5}                    {7} {3}  {0}

     递归代码如下:

public static void merg(int[] array)    {        if(array.length>1)//结束递归条件        {            //左半部分递归分拆            int[] left = new int[array.length/2];            System.arraycopy(array,0,left,0,array.length/2);            merg(left);            //右半部分递归分拆            int   rightIndex = array.length - array.length/2;            int[] right      = new int[rightIndex];                System.arraycopy(array,array.length/2,right,0,rightIndex);            merg(right);                                   //排好序的数组,用于下一步修改原数组的中间量            int[] temp = mergeSort(left,right);            //修改原数组            System.arraycopy(temp,0,array,0,temp.length);        }    }
      好了,已经分完了,开始治!

      就这个问题而言,小问题就是将两个元素排序,然后再合并成分开前的数组

      步骤分解:(递归出)

                一

                      1).        {2 1 8 6 5}               {4 9 7 3 0 }

                      2).        {2 1 }   {8 6 5}          {4 9}     {7 3 0}

                      3).        {2} {1} {8}  {5 6}       {4} {9}   {3 7}  {0}

                      4).                         {6} {5}                  {7} {3}  {0}

                二

                      1).        {2 1 8 6 5}               {4 9 7 3 0 }

                      2).        {1 2 }   {5 6 8}          {4 9}    {0 3 7}

                      3).        {2} {1}  {8}  {5 6}      {4} {9}   {3 7}     {0}

                      4).                         {6} {5}                   {7} {3}  {0}

                三

                      1).        {1 2 5 6 8}               {0 3 4 7 9}

                      2).        {1 2 }   {5 6 8}          {4 9}     {0 3 7}

                      3).        {2} {1} {8}  {5 6}       {4} {9}   {3 7}     {0}

                      4).                         {6} {5}                   {7} {3}  {0}  

               好了,下面说下怎么将两个数组合并成一个数组的,
               我们仅详解第四步,将最后的两个数组合并成最终的结果
              首先定义一个新的数组temp长度是这两个数组的和


                       1。。 {1 2 5 6 8}              {0 3 4 7 9 }

                                     temp{0}


                2。。{1 2 5 6 8}               {03 4 7 9 }

                                     temp{0 1}


                3。。{1 2 5 6 8}               {03 4 7 9 }

                                     temp{0 1 2}


                4。。{1 2 5 6 8}               {0 3 4 7 9 }

                                     temp{0 1 2 3 }


                5。。{1 2 5 6 8}               {0 3 4 7 9}

                                     temp{0 1 2 3 4}


                6。。{1 2 5 6 8}               {0 3 4 7 9 }
                                     temp{0 1 2 3 4 5}

                7。。{1 2 5 6 8}               {0 3 47 9}

                                    temp{0 1 2 3 4 5 6}

 

                8。。{1 2 5 6 8}               {0 3 4 7 9 }

                                    temp  {0 1 2 3 4 5 6 7 }


                9。。{1 2 5 6 8}               {0 3 4 7 9 }
                                    temp  {0 1 2 3 4 5 6 7 8}
               好了,到这先停一下,因为第一个数组如若再向下移就会越界了,所以结束这一部分的归并。

               开始下一部分的归并。将第二个数组(未归并完的数组)直接copy到temp中,虽然目前它只有一个元素。依然要这样做。
                                   temp   {0 1 2 3 4 5 6 7 8 9}

              代码如下:

public static int[] mergeSort(int[] left,int[] right)    {        //存放排序后的数组        int[] temp       = new int[left.length+right.length];        int   leftIndex  = 0;        int   rightIndex = 0;        int   tempIndex  = 0;                //合并        while(leftIndex<left.length&&rightIndex<right.length)        {            if(left[leftIndex]<right[rightIndex])                temp[tempIndex++] = left[leftIndex++];            else                temp[tempIndex++] = right[rightIndex++];        }                //合并不需要排序的元素        while(leftIndex<left.length||rightIndex<right.length)        {            if(leftIndex<left.length)                temp[tempIndex++] = left[leftIndex++];            else                temp[tempIndex++] = right[rightIndex++];        }        return temp;    }

          好了,写个主函数测试下吧。

public static void main(String[] args){int[] array = {1,2,3,4,5,6,7,8,9,0};merg(array);for(int i = 0;i<array.length;i++)System.out.print(array[i]+" ");System.out.println();}

0 0