论分治与归并思想
2019-08-16 08:01:14来源:博客园 阅读 ()
论分治与归并思想
归并排序
要想了解归并思想,就离不开对归并排序的理解,从前看别人的代码百思不得其解,后来看到一张图片顿时领悟,附下:
每次比较两个数组,注意可以是一个数组的两个不同的区间,每次将较小的数存储在一个临时数组中,这样就完成了归并排序。当然,前提是这两个数组是有序的,那么,问题是,如何让这两个数组是有序的呢,这就用到了递归。
merge_sort(left, mid);
merge_sort(mid+1, right);
为什么要用递归来实现呢,看下一张图片。
例题
如果只是说理论就显得苦涩难懂,下面贴一个来自洛谷的题目,小试身手。
https://www.luogu.org/problem/P1908
详细讲解已经在代码注释中标明
#include<bits/stdc++.h>
using namespace std;
int N;
int a[100000+10], temp[100000+10];
long long ans = 0; //ans用于记录逆序对的数量
void merge_sort(int l, int r)
{
if(l == r) return ;
int k = 0 ,mid = (l + r)/2;
merge_sort(l, mid);
merge_sort(mid+1, r);
//注意一定要先递归,这样就可以保证l ~ mid区间、mid + 1 ~ r区间已经完成了从小到大的排序
int i = l, j = mid + 1;
while(i <= mid && j <= r)
{
if(a[i] < a[j])
temp[k++] = a[i++]; //将较小的数字存储在临时数组中
else
{
temp[k++] = a[j++];
ans += mid - i + 1; //因为a[i]-a[mid]按递增顺序排列 所以a[j]之前有mid-i+1对逆序对
}
}
while(i <= mid) //如果a[i...mid]有剩余
temp[k++] = a[i++];
while(j <= r) //如果a[j...r]有剩余
temp[k++] = a[j++];
for(k = 0; k <= (r - l); k++)
a[l + k] = temp[k]; //这里就完成了两块区间的有序归并
}
int main()
{
std::ios::sync_with_stdio(false);
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
cin >> N;
memset(a, 0, sizeof(a));
memset(temp, 0, sizeof(temp));
for(int i = 0; i < N; i++)
cin >> a[i];
merge_sort(0, N-1);
cout << ans << endl;
}
以上代码同样可以用于排序(采用了分治排序)
参考博客:https://www.cnblogs.com/mrblug/p/5763138.html
原文链接:https://www.cnblogs.com/KeepZ/p/11319204.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 序列归并 2020-02-19
- MergeSort(归并排序)原理及C++代码实现 2020-01-14
- C++分治策略实现快速排序 2019-10-08
- 插入排序 2019-10-08
- 重写二路归并排序 2019-09-23
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash