分治法 归并排序 加上逆序数求法
来源:互联网 发布:java注释有几种 编辑:程序博客网 时间:2024/06/06 00:39
分治法:
字面意义就是分而治之,把大的问题分成小的相似的子问题,递归的解决掉小问题,最终合起来解决大问题
分治法在每层递归时都有三个步骤:
分解原问题为若干子问题,这些子问题都是原问题的规模较小的实例;
解决这些子问题(递归)
合并这些子问题的解
分治法的一个应用就是归并排序,是一种稳定的快速的排序,(Θ(n*logn))
分解: 待排序的n为 n/2 n/2两组
解决: 归并排序递归的解决两组
合并: 合并两个已经有序的子序列
关键步骤为合并步(Merge),需要Θ(n)时间
伪代码如下:
Merge(A,p,q,r) N1 = q-p+1;N2 = r-q;New arrays L[N1 + 2], R[N2+2];For(i= 1; i<=N1;i++ )L[i] = A[p+i-1];For(j = 1;j <=N2;j++)R[j] = A[q+j];L[N1+1] = 无穷大;R[N2+1] = 无穷大;//哨兵牌 避免每次检查是否有空I = 1; j= 1;For(k = p; k<=r;k++)If(L[i] < R[j])A[k] = L[i];i++;ElseA[k] = R[j];j++;
MergeSort(A,p,r):If(p<r){ Q = (p+r)/2;mergeSort(A,p,q);mergeSort(A,q+1,r);merge(A,p,q,r);}
C++代码如下:
#include<iostream>#include<cstdio>using namespace std;const int mm = (1<<30);int count = 0;//用来求逆序数
void mergee(int A[], int p, int q, int r){ int n0 = r-p+1, n1 = q-p+1,n2 = r-q; int L[(n0+1)/2], R[(n0+1)/2]; int i,j; for(i=1;i<=n1;i++) L[i] = A[p+i-1]; for(j = 1;j<=n2;j++) R[j] = A[q+j]; L[n1+1] = mm; R[n2+1] = mm; i = 1; j = 1; int k; for(k = p; k<=r;k++) { if(L[i]<=R[j])//加上等号比较保险 { A[k] = L[i]; i++; } else { A[k]= R[j];j++; count += n1-i+1;//后面解释 } }}
void merge_sort(int A[], int p, int r){ if(p<r) { int q = (p+r)/2; merge_sort(A,p,q); merge_sort(A,q+1,r); mergee(A,p,q,r); }}
int main(){ int n; while(cin>>n) { int num[n+2]; for(int i = 1; i<=n; i++) cin>>num[i]; merge_sort(num,1,n); for(int i = 1; i<=n; i++) cout<<num[i]<<" "; cout<< count<<endl; }}
归并排序算法分析:
分解:计算中间位置 Θ(1);
解决: 2* T(n/2);
合并:Θ(n);
T(n) = Θ(1)(n == 1)
T(n) = Θ(n) + 2*T(n/2) (n>1);
关于逆序数的补充
如果排在前面的数比排在后面的数大,那就构成了一对逆序,比如
1 6 8 2 7
逆序有 6-2 8-2 8-7
用分治法的思想呢, 当两组数分别是(1,6,8) (2,7)时,进行归并排序时
先拿出左边的1, 再拿出右边的2放进来时,实际要放在6的前面,因为2比较小,因此对2来讲,就有逆序6和8两个,也即是左边组的长度从减掉前面的 用上面的代码表示就是 n1-i+1注意是n1而不是中间的q,而再选左边的6时,不会有位置的变化,不会产生逆序
0 0
- 分治法 归并排序 加上逆序数求法
- 逆序数 归并排序求法
- 分治法之归并排序2-求解逆序数
- 归并排序;分治算法;复杂度nlgn;附加逆序数算法;
- 分治之归并排序 求排列的逆序数
- 逆序对的求法 归并排序
- 归并排序,逆序数
- 归并排序 逆序数
- 归并排序+逆序数
- 归并排序 + 逆序数
- 归并排序与分治法求逆序对数
- 归并排序/归并排序求逆序数
- 分治法 逆序数
- 归并排序 and 逆序对数(分治)
- 归并排序,求逆序数
- 归并排序求逆序数
- 逆序数--归并排序-nyoj117
- 归并排序求逆序数
- 死锁和活锁
- POJ 2752 (KMP)
- 对话框绘图的背景擦除
- Android WebView上传的FileUtils工具类
- 码神-day6-java
- 分治法 归并排序 加上逆序数求法
- 集群、双机、负载均衡、HA、HPC、NLB、DRBD
- 数据接收之环形缓冲 TCP粘包处理-RingBuf方法
- JSP中Session用法及其属性介绍
- NGUI学习笔记2-窗口及子类
- 使用友盟组件报错
- Java - PAT - L1-027. 出租(天梯赛决赛题目)
- Android中自定义属性
- Spring之helloworld,Spring基础知识解释。