归并排序(dart实现)

归并排序

1945年由约翰:冯.诺伊曼(John von Neumann)首次提出

执行流程

  1. 不断的将当前序列品骏分割成两个子序列,直到不能再分割(序列中只剩下1个元素)
  2. 不断的将两个子序列合并成1个有序序列,直到最终只剩下一个有序序列

思路

  • 将一个数组归并排序,就是将左边的数组归并,右边的数组归并,然后进行合并,递归下去

  • 合并的思路:

    • 创建两个索引分别指向两个数组,
    • 将两个归并的数组都从头开始,
    • 比如发现左边数字比较小,拿出左边数字放入大数组,左边索引右移一位,
    • 发现右边的数字比较小,拿出右边的数字放入大数组,右边索引右移一位
    • 最终两个索引都到最后即可

    难点:
    需要合并的两个数组在同一个数组中,并且是挨在一起,
    解决方法,将左边的数组备份出来

dart代码


class MergeSort<T extends Comparable<T>> extends Sort<T> {
  List<T> leftCopy ;
  @override
  sort() {
    leftCopy = List(list.length>>1);//提前定义一般长度的左边长度
    _sort(0, list.length);
  }

  ///
  /// Author: liyanjun
  /// description:  对 [begin, end) 范围的数据进行归并排序
  ///
  _sort(int begin, int end) {
    if (end - begin < 2) return;
    int mid = (end + begin) >> 1; //找到中间位置
    _sort(begin, mid); //左边归并排序
    _sort(mid, end); //右边归并排序
    _merge(begin, mid, end); //合并
  }

  ///
  /// Author: liyanjun
  /// description: 归并
  ///将 [begin, mid) 和 [mid, end) 范围的序列合并成一个有序序列
  _merge(int begin, int mid, int end) {
    int leftCopyIndex = 0; //左边的数组
    int leftCopyLength = mid - begin; //左边数组长度
    int rightIndex = mid; //右边数组索引 基于原数组
    int resultIndex = begin; //覆盖的索引
    for (var i = 0; i < leftCopyLength; i++) {
      leftCopy[i]  = list[begin + i];
    } //复制左边的数组
    while (leftCopyIndex < leftCopyLength) {
      //复制的数组遍历完即可,因为两个都是有序数组
      //如果左边数组元素小于右边数组元素,将右边数组元素放在目标索引 ,反之左边数组放入目标索引
      if (rightIndex < end && cmpElement(list[rightIndex], leftCopy[leftCopyIndex]) < 0) {//考虑稳定性,所以不用等于好
        list[resultIndex] = list[rightIndex];
        rightIndex += 1; //右边数组右移动一位
      } else {
        list[resultIndex] = leftCopy[leftCopyIndex];
        leftCopyIndex += 1; //左边数组右移动一位
      }
      resultIndex += 1; //目标数组索引移动一位
    }
  }


}

执行结果

排序前 :[20, 12, 6, 20, 17, 14, 13, 4, 19, 10]
排序后 :[4, 6, 10, 12, 13, 14, 17, 19, 20, 20]
【MergeSort<num>】
耗时:0.002s (2ms)     比较:22    交换:0
-----------------

复杂度分析

归并排序花费的时间

T(n) = 2*T(n/2) + O(n)
推导过程:
\because
T(1) = O(1);
T(n)/n = T(n/2)/(n/2) + O(1);

S(n) = T(n)/n
则有
S(1)=O(1)
S(n)= S(n/2)+O(1) = S(n/4)+O(2) = S(n/8)+O(3)=S(n/2^k)+O(k)=S(1)+O(logn)= O(logn)

\therefore
T(n) = n * S(n) = n*O(logn) = O(nlogn)

由于归并排序总是平均分割子序列,所以最好、最坏、平均时间复杂度都是O(nlogn),属于稳定排序
从代码中不难看出:归并排序的空间复杂度是 O(n/2 + logn) = O(n)
n/2用于临时存放左侧数组,logn是因为递归调用

常见的递推公式和时间复杂度

递推式 时间复杂度
T(n) = T(n/2) + O(1) O(logn)
T(n) = T(n-1) + O(1) O(n)
T(n) = T(n/2) + O(n) O(n)
T(n) = 2*T(n/2) + O(1) O(n)
T(n) = 2*T(n/2) + O(n) O(nlogn)
T(n) = T(n-1) + O(n) O(n^2)
T(n) = 2*T(n-1) + O(1) O(2^n )
T(n) = 2*T(n-1) + O(n) O(2^n)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343