C++编程:C++归并排序实现(算法导论)

 

  算法导论上的下标是从1开始的,但是为了和c++ STL的设计思想一致,所有函数的实现统一用左闭右开区间。中间修改了很多次,因为下标修改不是很容易就改掉的,需要始终维持循环不变式,稍微一个步骤出错就会使结果有些错误。

  #include

  #include

  #include

  #include

  using namespace std;

  void merge(int *A, int p, int q, int r) { //merge [p, r),左闭右开区间

  int n1 = q - p, n2 = r - q; //注意数量的变化与书上的不同,使用左闭右开区间的优势就是统一数量的形式表示

  int *L = new int[n1], *R = new int[n2];

  for (int i = 0; i < n1; ++i) //L[0, n1) <== A[p, q)

  L[i] = A[p+i];

  for (int i = 0; i < n2; ++i) //R[0, n2) <== A[q, r)

  R[i] = A[q+i]; //此处不是q+i+1

  int i = 0, j = 0;

  int k = p;

  while (i < n1 && j < n2) {

  if (L[i] <= R[j])

  A[k++] = L[i++];

  else

  A[k++] = R[j++];

  }

  while (i < n1) //由于没有了哨兵,需要添加多余元素

  A[k++] = L[i++];

  while (j < n2)

  A[k++] = R[j++];

  delete [] L;

  delete [] R;

  }

  void merge_sort(int *a, int p, int r) { //调用接口 merge_sort(a, 0, len), 不是(a, 0, len-1)了

  if (p < r - 1) { //此时不是p < r了,左闭右开区间当p>=r-1时子数组最多一个元素

  int q = p + (r - p)/2;

  merge_sort(a, p, q);

  merge_sort(a, q, r); //注意接口统一了,这个不是(a, q+1, r)而是(a, q, r)了,左闭右开的好处

  merge(a, p, q, r);

  }

  }

  int main()

  {

  srand(time(NULL));

  int n;

  while (cin 》 n) {

  int a[n];

  for (int i = 0; i < n; ++i)

  a[i] = rand() % n;

  for (int i = 0; i < n; ++i)

  printf("%d ", a[i]);

  printf("n");

  merge_sort(a, 0, n);

  for (int i = 0; i < n; ++i)

  printf("%d ", a[i]);

  printf("n");

  }

  }

  最后用了几万组测试数据,得出的结果均与stl里的sort结果一样, 基本说明这个代码是正确的。

时间: 2024-07-30 12:36:59

C++编程:C++归并排序实现(算法导论)的相关文章

【算法导论】排序(一)

虽然久闻大名,但第一次接触算法导论,是看了网易公开课MIT的<算法导论>课,记得 第一集就讲到了 插入排序和归并排序. 几个星期前也买了算法导论这本书,准备慢慢啃~ 这星期主要在看前两 部分,除了对于讲渐进时间.递归式分析这些东西感到云里雾里的,其它的都就 感觉越看越有觉得入 迷,果然不愧是一本经典之作 好吧,开始.本文主要是用C++把书中的算法实现,以及一些笔记. 一.插入排序. 插入算法的设计使用的是增量(incremental)方法:在排好子数组A[1..j- 1]后,将 元素A[ j]

【算法导论】排序 (二):堆排序

四.(1)堆排序 第一次听堆排序是在107lab听忠哥讲的,但是没讲怎么实现.那时刚看了数据结 构的二叉树,还以为要通过指针建立二叉树的方式来实现,觉得挺难的. 其实堆排序实现没有想象中 的那么难. "堆"这个词最初是在堆排序中提出来的,但后来就逐渐指"废料收集储存区",就像程 序设计语言Lisp和Java中所提供的设施那样.我们这里的堆数据结构不是废料收集存储区. 堆排序的 运行时间与归并排序一样为O(n lg n),  但是一种原地(in place)排序. (

算法导论-1

算法导论一共7个部分,第一第二部分可以迅速看过:第三部分比较基础,要打好基础:第四部分很经典的几个算法,要认真琢磨:第五部分b树.二项堆.等:第六部分图算法,基本的几个算法掌握:第七部分是算法研究,学习字符串匹配等.   这一遍学习要注意课后题目了,不能像第一次那样草草看过! 2013.4.1----4.3  第一部分 基础知识  第二部分 排序和顺序统计学  编程珠玑是一本耐看的书,所以重在把握其中的思想.  这个从第八章开始,之前的已经在假期看过了.

看算法导论有感(1)——谈谈算法的五性对用户体验的影响

做程序的人,都知道了算法的5性--可行性,健壮性,有穷性,高效性,可读性. 这15个字谁都会说了,但是,你是否真正的思考过这个对当今程序界最最重要的用户体验的思考. 过去,我也没多做思考,但是,看了mit的算法导论公开课,我却是觉得一个好的算法, 确实严格遵从算法算法五性. ①可行性--算法原则上能够精确地运行,而且人们用笔和纸做有限次运算后即可完成.算法肯定要可行的,不可行的话,是一坨shit,一般可行性是与硬件息息相关.比如,10年前,你要先像现在的搜索引擎一样能够做视搜索,做各种各样的算法

算法导论 最大子数组数量问题

问题描述 算法导论 最大子数组数量问题 进行问题变换后,检查的子数组数量为什么会减少呢. 暴力求解方法有n(n-1)/2 种组合,进行问题变换后为什么有(n-1)(n-2)/2种组合呢,组合的数量应噶事保持不变的啊. 解决方案 http://www.cnblogs.com/chinaxmly/archive/2012/10/10/2718621.html 复杂度降低到O(n)

高效算法的常用技术(算法导论)

对于高效算法, 有些比较简单的技术, 如分治法, 随机化, 和递归求解技术. 这边介绍些更为复杂的技术, 动态规划, 贪心算法 当对于复杂问题设计算法时, 首先会想到使用分治法 来解决, 分而治之, 一个很有哲理性的思路, 再复杂的问题都可以不断分解到你可以轻松解决的粒度, 把所有简单问题都解决完后, 组合在一起就得到了复杂问题的解, 可以看出其中典型的递归求解的思路. 使用分治法的要求, 各个子问题是独立 的 (即不包含公共的子子问题,子问题不重叠 ). 如果子问题重叠, 用分治法就比较低效,

实际编程中需要多少算法?

问题描述 实际编程中需要多少算法? 实际编程(主要是Android开发方向)中需要多少算法?有必要参加ACM校队吗? 解决方案 低端开发者(典型的xxx方向开发者)不需要任何算法,这种开发者我们叫做"胶水程序员",他们不创造可以重用的,有价值的程序,他们的工作是把现成的组件和框架按照需求粘合起来. 程序员当然需要算法.因为实际项目中各种各样的需求,没有任何现成的算法可以直接解决. 解决方案二: 就拿现在你用的这个csdn问答为例,当你输入一个问题,它会自动给你匹配一些标签.旁边有其他相

求问算法导论中一个非常简单的对数问题

问题描述 求问算法导论中一个非常简单的对数问题 求问算法导论中一个非常简单的对数问题.额,各位不要笑话啊. 请问这两个对数是如何推出相等的啊,用的是哪个公式啊? 只记得这个公式了.... 解决方案 解决方案二: begin{align} ln(3^{log_4^n}) & = ln(n^{log_4^3}) log_4^ncdot ln(3) & = log_4^3cdot ln(n) frac{ln(n)}{ln(4)}cdot ln(3) & = frac{ln(3)}{ln(

【算法导论】排序算法总结

排序算法总结         从六月初开始看算法导论,陆陆续续看了有2个月了,但实际看的时间只有半个月左右.这期间都忙着找导师.期末考试,同时还回家修养了十来天.真正专心的看算法是在离家返校后,由于没有考试和作业的烦恼,天天都沉浸在算法中,感觉效率较高.这段时间学到的东西较多,下面来总结一下:         学到的排序算法可以分为两类:比较排序.非比较排序.(这些排序算法的详细介绍及c程序实现在本文末都给出了链接,欢迎参考与指正!)         比较排序有:插入排序法.合并排序法.堆排序法