归并排序详解
来源:互联网 发布:思维脑图软件 编辑:程序博客网 时间:2024/05/01 08:09
分治法在每层递归时都有三个步骤:
1.分解原问题为若干个子问题,这些子问题是原问题规模较小的实例;
2.解决子问题,递归求解各子问题,如果子问题规模足够小,则直接求解;
3.合并子问题得到原问题的解。
归并排序完全遵循分治法:
1.分解待排序的n个元素的序列,分成各具有n/2个元素的两个子序列;
2.使用归并排序递归地排序两个子序列;
3.合并两个已排序的子序列得到已排序的答案。
当待排序的子序列只有一个元素时,递归开始“回升”,这种情况下不要做任何工作,因为长度为1的每个序列都已经排好。
#include <bits/stdc++.h>using namespace std;//注意区间状况是[left, mid], (mid, right];void merge_test(int* a, int left, int mid, int right) { int i, j; int n1 = mid - left + 1; int n2 = right - mid; //建立新数组L[n1 + 1], R[n2 + 1]; int L[n1 + 1], R[n2 + 1]; for (i = 0; i < n1; i++) { L[i] = a[left + i]; } for (i = 0; i < n2; i++) { R[i] = a[mid + i + 1]; } L[n1] = 0x3f3f3f3f, R[n2] = 0x3f3f3f3f;//设为无穷大可不必考虑数组为空的情况 //合并, 从小到大 i = j = 0; for (int k = left; k <= right; k++) { if (L[i] <= R[j]) { a[k] = L[i++]; } else { a[k] = R[j++]; } }}//区间为[left, right];void merge_sort(int* a, int left, int right) { if (left < right) {//当left = right时区间内只有一个元素,不进行递归; int mid = (left + right)/2; merge_sort(a, left, mid); merge_sort(a, mid + 1, right); merge_test(a, left, mid, right); }}int main(){ int n; while (cin >> n) { int a[n]; for (int i = 0; i < n; i++) { cin >> a[i]; } //归并排序,从小到大 merge_sort(a, 0, n - 1);//注意用闭区间 //测试 int flag = 0; for (int i = 0; i < n; i++) { if (flag++) cout << " "; cout << a[i]; } cout << endl; }}
1 0
- 排序详解:归并排序
- 归并排序详解
- 归并排序详解
- 归并排序详解_legend
- 归并排序--详解
- 归并排序详解
- 归并排序法详解
- 归并排序详解
- 归并排序详解
- 归并排序 详解
- 归并排序详解
- java归并排序详解
- 归并排序详解
- 归并排序详解
- 详解归并排序
- 归并排序 -JAVA详解
- 排序详解之归并排序
- 2-路归并排序详解
- Spring Beans实例化
- 使用MapReduce统计微博关注数据
- 前端面试答案整理之js
- 如何在win10本地安装wordpress测试环境
- Java提高篇(二七)-----TreeMap
- 归并排序详解
- 电子邮件系统
- IPSec VPN的原理
- 堆排序、归并排序、快速排序总结
- RxJava2 源码解析(一)
- 突然自己好忙啊~
- 模!!!!!板
- Pdf File Writer 中文应用(PDF文件编写器C#类库)
- 成为专业程序员路上用到的各种优秀资料、神器及框架