算法竞赛——归并排序算法

分治法
划分问题:把序列分成元素个数尽量相等的两半
递归求解:把两半元素分别排序
合并问题:把两个有序表合并成一个

借鉴RuJia的精妙的合并过程

void merges2(int *a, int lef, int righ) {// 递归边界if(lef == righ) {return ;}// 取中值int center = lef + (righ - lef) / 2;// 递归左半merges2(a, lef, center);// 递归右半merges2(a, center + 1, righ);// 合并左半和右半// 该大小为左半右半大小之和int totalSize = righ - lef + 1;int tmp[totalSize];int n = lef;int m = center + 1;int i = 0;// 左半右半其一不为空while(n <= center || m <= righ) {// 右半为空 或者 左半不为空且左半值小于右半值if(m > righ || (n <= center && a[n] <= a[m])) {// 从左半数组复制到临时空间tmp[i++] = a[n++];} else {// 从右半数组复制到临时空间tmp[i++] = a[m++];}}n = lef;// 将临时数组的值放入原数组for(int i = 0; i < totalSize; i++) {a[n++] = tmp[i];}
}

自己写的,合并过程没那么精妙,但是非常直观

void merges(int *a, int lef, int righ) {// 递归边界if(lef == righ) {return ;}// 取中值int center = lef + (righ - lef) / 2;// 递归左半merges(a, lef, center);// 递归右半merges(a, center + 1, righ);// 合并左半和右半// 该大小为左半右半大小之和int totalSize = righ - lef + 1;int tmp[totalSize];int n = lef;int m = center + 1;int i;for(i = 0; i < totalSize; i++) {// 左半为空,或右半为空if(n > center || m > righ) {break;}// 左边的值int leftV = a[n];// 右边的值int rightV = a[m];if(leftV <= rightV) {tmp[i] = leftV;n++;} else {tmp[i] = rightV;m++;}}// 如果左半不为空for(int j = n; j <= center; j++) {tmp[i++] = a[j];}// 如果右半不为空for(int j = m; j <= righ; j++) {tmp[i++] = a[j];}n = lef;// 将临时数组的值放入原数组for(int i = 0; i < totalSize; i++) {a[n++] = tmp[i];}
}

测试主程序

#include <iostream>using namespace std;// 归并排序
// 分治法
// 划分问题:把序列分成元素个数尽量相等的两半
// 递归求解:把两半元素分别排序
// 合并问题:把两个有序表合并成一个
void merges(int *a, int lef, int righ) {// 递归边界if(lef == righ) {return ;}// 取中值int center = lef + (righ - lef) / 2;// 递归左半merges(a, lef, center);// 递归右半merges(a, center + 1, righ);// 合并左半和右半// 该大小为左半右半大小之和int totalSize = righ - lef + 1;int tmp[totalSize];int n = lef;int m = center + 1;int i;for(i = 0; i < totalSize; i++) {// 左半为空,或右半为空if(n > center || m > righ) {break;}// 左边的值int leftV = a[n];// 右边的值int rightV = a[m];if(leftV <= rightV) {tmp[i] = leftV;n++;} else {tmp[i] = rightV;m++;}}// 如果左半不为空for(int j = n; j <= center; j++) {tmp[i++] = a[j];}// 如果右半不为空for(int j = m; j <= righ; j++) {tmp[i++] = a[j];}n = lef;// 将临时数组的值放入原数组for(int i = 0; i < totalSize; i++) {a[n++] = tmp[i];}
}void merges2(int *a, int lef, int righ) {// 递归边界if(lef == righ) {return ;}// 取中值int center = lef + (righ - lef) / 2;// 递归左半merges2(a, lef, center);// 递归右半merges2(a, center + 1, righ);// 合并左半和右半// 该大小为左半右半大小之和int totalSize = righ - lef + 1;int tmp[totalSize];int n = lef;int m = center + 1;int i = 0;// 左半右半其一不为空while(n <= center || m <= righ) {// 右半为空 或者 左半不为空且左半值小于右半值if(m > righ || (n <= center && a[n] <= a[m])) {// 从左半数组复制到临时空间tmp[i++] = a[n++];} else {// 从右半数组复制到临时空间tmp[i++] = a[m++];}}n = lef;// 将临时数组的值放入原数组for(int i = 0; i < totalSize; i++) {a[n++] = tmp[i];}
}void mergeSort(int *a, int n) {
//    merges(a, 0, n - 1);merges(a, 0, n - 1);
}int main() {int a[] = {-1, 3, 3, 5, 5, 41, 5435, -11, 3423, 4432, -4421, 34432};int n =12;cout << "排序前: ";for(int i = 0; i < n; i++) {cout << a[i] << " ";}cout << endl;mergeSort(a, n);cout << "排序后: ";for(int i = 0; i < n; i++) {cout << a[i] << " ";}cout << endl;return 0;
}

输出结果

排序前: -1 3 3 5 5 41 5435 -11 3423 4432 -4421 34432
排序后: -4421 -11 -1 3 3 5 5 41 3423 4432 5435 34432Process returned 0 (0x0)   execution time : 0.177 s
Press any key to continue.

算法竞赛——归并排序算法相关推荐

  1. 排序算法:归并排序算法实现及分析

    归并排序算法介绍 归并排序(Merging Sort)就是利用归并的思想实现排序的放.它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个 ...

  2. 算法设计与分析 ——插入排序算法与归并排序算法比较

    插入排序算法与归并排序算法比较 实验目的 通过插入排序算法与归并排序算法效率对比体会算法在求解问题中的重要性. 实验内容 分别编写函数实现插入排序算法和归并排序算法: 利用随机函数产生大量数据存入数组 ...

  3. java的归并排序算法_归并排序算法Java实现

    一. 算法描述 归并排序采用了分治策略(divide-and-conquer),就是将原问题分解为一些规模较小的相似子问题,然后递归解决这些子问题,最后合并其结果作为原问题的解. 归并排序将待排序数组 ...

  4. 【排序算法】归并排序算法原理

    归并排序 概念 使用前提 算法思路 适用场景 算法描述 递归法(Top-down) 分而治之 迭代法(Bottom-up) 迭代 概念   归并排序是建立在归并操作上的一种有效的排序算法.    该算 ...

  5. 蓝桥杯算法竞赛备考算法归纳总结

    蓝桥备考基础算法归纳 暴力.贪心 递归.递推 二分.快排 深度优先搜索.广度优先搜索.回溯 字符串处理 双指针 动态规划 各类背包问题 数论 全排列.组合 素数.最大公约数.最小公倍数.欧几里得gcd ...

  6. 算法竞赛——快速排序

    算法竞赛--快速排序 快速排序算法和归并排序算法都可以用分治法的思想来解决,其区别是归并排序是等份左右划分,而快速排序则是按标兵进行划分,也不需要合并. 分治三步骤 划分问题:按标兵元素,将序列分成左 ...

  7. JavaScript实现十种经典排序算法(js排序算法)

    冒泡排序算法 冒泡排序(Bubble Sort)是一种简单直观的排序算法.冒泡排序算法的步骤描述如下: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一 ...

  8. 【数据结构与算法】【算法思想】分治算法

    贪心算法 回溯算法 分治算法 动态规划 MapReduce本质就是分治算法,是Google大数据处理的三驾马车之一,另外两个是GFS和Bigtable.它在倒排索引,PageRank计算,网页分析等搜 ...

  9. 排序算法(五)——堆排序算法详解及Python实现

    本文目录 一.简介 二.算法介绍 三.代码实现 排序算法系列--相关文章 一.简介 堆排序(Heap Sort)算法,属于选择排序类,不稳定排序,时间复杂度O(nlogn). 堆排序由Floyd和Wi ...

最新文章

  1. freescale imx6 编译 linux ltib,TQIMX6Q技术分享——LTIB安装配置(转)
  2. LeetCode 167. Two Sum II - Input array is sorted--Python解法
  3. php网站白页面_php页面空白怎么回事 php出现空白页的解决方法
  4. 【LeetCode从零单排】No 191.Number of 1 Bits(考察位运算)
  5. BZOJ 2003 [Hnoi2010]Matrix 矩阵
  6. 数字签名和数字信封之间的介绍
  7. 解决方案:超卖(Redis原子队列)
  8. TensorFlow保存和恢复模型的方法总结
  9. 在线修改域控的IP和机器名
  10. Thinkphp3.2在IIS中使用ISAPI_Rewrite去除index.php
  11. tomcat7-maven-plugin-用于部署WAR的Tomcat Maven插件
  12. 编写matlab程序设计状态反馈增益阵,利用MATLAB设计状态观测器.pdf
  13. 设计一个单选题考试程序python_Python123计算机等级考试二级Python语言与程序设计通关指南七Python 计算生态...
  14. Kali Linux签名失效的解决方法
  15. java 中的 while和 do...while语句的区别
  16. 中望CAD填充图形不显示
  17. VIVADO2018与SYNPLIFY联合使用
  18. 小组焦点座谈的基本过程
  19. 一个月 5000 的公务员和一个月 1.5 万的程序员,你会选择当哪一个?
  20. 每日优鲜深陷“破产风波”,生鲜电商路在何方?

热门文章

  1. 设置网格_500ETF网格设置
  2. Java Socket TeXT_FULL_WRITING 等问题解决
  3. 【Python】斐波那契数列
  4. C#LeetCode刷题之#455-分发饼干(Assign Cookies)
  5. python requests verify=True vs verity=Flase
  6. 不需要登陆的灵感笔记私人版正式上线,迭代优化中。
  7. node和npm是什么_什么是npm? 面向初学者的Node Package Manager教程
  8. html 比 htm 的载入速度快,htm和html
  9. python怎样实现界面的切换_python tkinter实现界面切换的示例代码
  10. Python编程各种推导式详解