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

    该算法基于一个简单的操作: 将两个有序的队列合成一个更大的有序队列。

    归并排序保证NlogN。

    原地归并的抽象算法(Abstract in-place merge):

    using System;
    namespace MergeSort
    {
        class Program
        {
            static char[] aux = new char[100];
            static void Main(string[] args)
            {
                char[] data = new char[] { 'R', 'S', 'T', 'Z', 'B', 'C', 'D' };
                merge(data,0, 3, 6); // Expect result "BCDRSTZ"
            }
            public static void merge(char[] a, int lo, int mid, int hi)
            {
                // 将a[lo..mid] 和 a[mid+1..hi]归并
                int i = lo, j = mid + 1;
                for (int k = lo; k <= hi; k++)
                {
                    aux[k] = a[k];
                }
    
                for (int k = lo; k <= hi; k++) // merge to a[lo..hi]
                {
                    if     (i > mid)          a[k] = aux[j++];
                    else if (j > hi)          a[k] = aux[i++];
                    else if (aux[j] < aux[i]) a[k] = aux[j++];
                    else                      a[k] = aux[i++];
                }
            }
        }
    }

    如何确定i, j, k 的取值,根据下图可以观察出他们的规律:

    Top-down mergesort

    自顶向下的归并排序是基于原地归并排序的递归实现。是分治思想的典型例子。

    代码如下:

    // 将数组a[lo..hi]排序
    public static void sort(char[] a, int lo, int hi)
    {
      if (hi <= lo) return;
      int mid = lo + (hi - lo) / 2;
      sort(a, lo, mid); // 将左边排序
      sort(a, mid + 1, hi); // 将右边排序
      merge(a, lo, mid, hi); // 归并结果
    }

    Bottom-up mergesort:

    这种方法是先归并较小的,然后才是较大的,这样避免了递归调用:

    public void sort(char[] a)
    {
    int N = a.Length; char[] _aux = new char[N]; for (int sz = 1; sz < N; sz = sz + sz)// sz 子数组的大小 for (int lo = 0; lo < N - sz; lo += sz + sz)//sz 子数组的索引 { merge(a, lo, lo + sz - 1, Math.Min(lo + sz + sz - 1, N - 1)); } }

    观察下图就可以得出上面的算法,注意下图的sz = 1, 2 ,4...而不是 2,4, 8...:

    总体感觉这种分析方法很重要,如果把这些分析过程搞明白了,代码很容易。以后得改掉先代码后想的习惯。

  • 相关阅读:
    【转】Reactor与Proactor两种模式区别
    [转] 比较清楚的阻塞与非阻塞和同步与异步
    一眨眼已做开发十年
    【转】Linux CentOS内核编译:下载CentOS源码、编译2.6.32-220的错误(apic.c:819 error 'numi_watchdog' undeclared)
    [转] Makefile经典教程(掌握这些足够)
    [转]centos 下 autoconf版本升级
    centos安装CODEBLOCKS
    【转】linux 编译安装nginx,配置自启动脚本
    Install Qt creator
    LeetCode 983. Minimum Cost For Tickets
  • 原文地址:https://www.cnblogs.com/ming11/p/3710486.html
Copyright © 2011-2022 走看看