【算法之家】——归并排序

来源:互联网 发布:js call和apply的区别 编辑:程序博客网 时间:2024/05/17 08:18

【前言】

  归并排序(Merge Sorting)是与插入排序,交换排序,选择排序不同的一类排序方法,其不同之处在于要求待排序序列是由若干个有序子序列组成的。归并的含义是将两个或两个以上的有序表合并成一个新的有序表。

【内容】

   

对于归并排序的基本的合并过程我们可以用一个倒二叉树来表示:

    

第一步进行分组:

  /// <summary>        /// 将数组n进行分组,确定每一组的数组的长度-常银玲-2016-9-29 21:13:28        /// </summary>        /// <param name="a">待排序的数组a</param>        /// <param name="n">数组的长度</param>     static void MergeSort(int[] a, int n,int[] b) {          int m = 1;  //表示将数组n非为了具有n个长度为m数组          while (m<n)          {              MergePass(a, b, n, m); //将数组a中有序列合并到b              m = 2 * m;  //采用的是二路归并排序算法!              MergePass(b, a, n, m); //将数组b中有序序列合并到a              m = 2 * m;          }      }

第二步就是根据分组进行合并:

 /// <summary>        /// 在含有n个记录的序列a中,将长度为h的两个相邻的有序子序列合并为长度为2h的有序序列,结果存入b中。        /// </summary>        /// <param name="a">表示待合并数组a</param>        /// <param name="b">表示新开辟的数组b</param>        /// <param name="n">数组a的长度</param>        /// <param name="h">代表的是相邻的两个数组的长度各位h</param>      static void MergePass(int[] a, int[] b, int n, int h) {            int i=0;  //设定了开始的下标,从0开始。           while (i <= n - 2 * h + 1) {               Merge(a, b, i, i + h - 1, i + 2 * h - 1); //将这两个相邻的合并的序列排序。                i += 2 * h;            }           if (i+h-1<n)           {               Merge(a, b, i, i + h - 1, n);            }           else           {               for (int t = i; t <= n; t++) {                   b[t] = a[t];               }           }                        }

第三步就是将合并之后的序列进行排序:

  /// <summary>        /// 将合并之后的数组中的数进行排序        /// </summary>        /// <param name="a">表示待合并数组a</param>        /// <param name="b">表示新开辟的数组b</param>        /// <param name="h">a的起始下标</param>        /// <param name="m">a的末尾下标</param>        /// <param name="n">a的末尾下标,也是新的数组的末尾下标</param>     static void Merge(int[] a, int[] b, int h, int m, int n) {            int k = h;            int j = m + 1;            while ((h <= m) && (j <= n)) {               if(a[h]<=a[j]){                  b[k] = a[h];                  h++;              }              else              {                  b[k] = a[j];                  j++;              }              k++;            }            while (h <= m) { b[k] = a[h]; h++; k++; }  //将a[h]......a[m]插入到了待排序的数组b的尾部            while (j <= n) { b[k] = a[j]; j++; k++; }  //将a[m+1].....a[n]剩余部分插入到b的尾部                }

【总结】

   归并算法中基础是合并,合并的方法就是比较子序列的第一个记录的键值,最小的一个就是排序后序列的第一个记录的键值。取出这个记录,继续比较各子序列现有的第一个记录的键值,便可以找出第二个记录。归并排序所需要的辅助存储量大。相对于而言我认为归并排序不难理解,但是如何将其用代码展现出来,抽象到所有的数组中是我在学习归并算法的时候的难题!还需要进一步的加强锻炼!

1 0
原创粉丝点击