算法导论 归并排序解决逆序数
来源:互联网 发布:周末网络个人理财申请 编辑:程序博客网 时间:2024/06/03 17:41
算法导论上对归并排序的算法描述如下
基本思想是将序列分成两部分 L R,然后合并,L R 是有序的
算法的合并过程:
Pseudocode:MERGE(A, p, q, r )n1 ← q − p + 1n2 ←r − qcreate arrays L[1 . . n1 + 1] and R[1 . . n2 + 1]for i ← 1 to n1do L[i ] ← A[p + i − 1]for j ← 1 to n2do R[ j ] ← A[q + j ]L[n1 + 1]←∞R[n2 + 1]←∞i ← 1j ← 1for k ← p to rdo if L[i ] ≤ R[ j ]then A[k] ← L[i ]i ←i + 1else A[k] ← R[ j ]j ← j + 1归并排序:
MERGE-SORT(A, p, r )if p < r Check for base casethen q ←(p + r)/2 DivideMERGE-SORT(A, p, q) // ConquerMERGE-SORT(A, q + 1, r ) // ConquerMERGE(A, p, q, r ) //combinec 语言的实现过程 数组下标从1(算法导论上的描述数组下标均从1开始)开始,0位置为0
#include"stdio.h"#define Type int#define MAX 1000#define false 0#define true 1 //0--1--2--3--4--5--6--7--8--9--10--11--12--13--14--15--16--17--18--19int a1[20] = {0, 4, 6, 9, 0, 3, 4, 8, 16,2, 4, 5, 7, 1, 2, 3, 6, 20, 31, 9 };void merge(int a[],int p,int q,int r){int n1 = q - p + 1;int n2 = r - q;int L[n1 + 2];int R[n2 + 2];L[0] = 0;R[0] = 0;int i,j,k;for(i = 1; i <= n1; i++){L[i] = a[i+p-1];}for(j = 1; j <= n2;j++){R[j] = a[q+j];}L[n1 + 1] = MAX;R[n2 + 1] = MAX; for(i = 0;i<n1+2;i++){printf("L[%d]:%d--",i,L[i]);}for(j = 0; j < n2+2;j++){printf("R[%d]:%d--",j,R[j]);}printf("\n");i = 1;j = 1;for(k = p; k <= r;k++){if(L[i] <= R[j]){a[k] = L[i];i++;}else{a[k] = R[j];j++;}printf("a[%d]:%d\n",k,a[k]);}}int merge_sort(int *a,int p,int r){int q;if(p < r) { q = (p+r)/2;merge_sort(a,p,q);merge_sort(a,q+1,r);merge(a,p,q,r);}else return 0;}void main(){int i;printf("\n");for(i = 0; i < 19; i++)printf("%d:%d,",i,a1[i]);printf("\n");merge(a1,9,12,16);for(i = 0; i < 19; i++)printf("%d:%d,",i,a1[i]);}
归并排序的应用: 计算逆序数int a2[6] = {0,5,3,2,1,7};int merge_inversions(int a[],int p,int q,int r){int n1 = q - p + 1;int n2 = r - q;int inversions,counted;int L[n1 + 2];int R[n2 + 2];L[0] = 0;R[0] = 0;int i,j,k;for(i = 1; i <= n1; i++){L[i] = a[i+p-1];}for(j = 1; j <= n2;j++){R[j] = a[q+j];}L[n1 + 1] = MAX;R[n2 + 1] = MAX;i = 1;j = 1;inversions = 0;counted = false;for(k = p; k <= r;k++){if(counted == false && R[j] < L[i]){inversions = inversions + n1 - i + 1;counted = true;}if(L[i] <= R[j]){a[k] = L[i];i++;}else{a[k] = R[j];j++;counted = false;}//printf("a[%d]:%d\n",k,a[k]);}return inversions;}计算逆序数的个数
int count_inversions(int *a,int p,int r){int inversions = 0;int q;if(p < r){q = (p+r)/2; inversions = inversions + count_inversions(a,p,q); inversions = inversions + count_inversions(a,q+1,r); inversions = inversions + merge_inversions(a,p,q,r);}return inversions;}void main(){int m = count_inversions(a2,1,5);printf("inversions:%d",m);}归并排序的另一种写法,用一个temp数组存储归并的结果,最后将temp里的值赋给a数组
#include <iostream>using namespace std;void merge(int a[],int left,int mid,int right,int temp[]){int l_n = left;int l_end = mid;int r_n = mid+1;int r_end = right;int k = 0;while (l_n <= l_end && r_n <= r_end){if (a[l_n] <= a[r_n]){temp[k++] = a[l_n++];}else{temp[k++] = a[r_n++];}}while(l_n <= l_end)temp[k++] = a[l_n++];while(r_n <= r_end)temp[k++] = a[r_n++];for (int i = 0; i < k; i++){a[left+i] = temp[i];cout<<"["<<left+i<<"]:"<<a[left+i];}cout<<endl;}void mergesort(int a[],int l,int r){if(l < r){int mid = (l + r)/2;mergesort(a,l,mid);mergesort(a,mid+1,r);int *temp = new int[r-l+1];merge(a,l,mid,r,temp);}else return;}int a1[20] = {0, 4, 10, 9, 32, 3, 14, 8, 16,2, 19, 5, 7, 1, 37, 17, 6, 20, 31, 9 }; int main(){mergesort(a1,0,19);for (int i = 0; i < 20; i++){cout<<"-"<<a1[i];}system("pause");return 0;}
- 算法导论 归并排序解决逆序数
- 归并排序-求逆序数算法
- 算法 -- 计算逆序数 , significant逆序数 归并排序
- 归并排序,逆序数
- 归并排序 逆序数
- 归并排序+逆序数
- 归并排序 + 逆序数
- 【算法】归并排序(可求逆序数或逆序对)
- 【算法导论】归并排序
- [算法导论]归并排序
- 算法导论-----归并排序
- 【算法导论】归并排序
- 算法导论-归并排序
- 算法导论-归并排序
- 算法导论 归并排序
- 算法导论-归并排序
- 《算法导论》--归并排序
- 算法导论--归并排序
- javascript中showModalDialog和showModelessDialog区别
- 代码疑云(4)-类的sizeof值
- window 下的 apache 无法启动排查
- 新起点
- 工作总结
- 算法导论 归并排序解决逆序数
- ORACLE使用触发器更新数据
- Struts2+Spring2+Hibernate3整合
- static的作用
- Mysql利用/*!select*/ 突破防注入
- 域内计算机和用户获取
- 一份比较详细的DOS命令说明!
- 另类抓win hash法
- 最新Discuz! X1- 1.5 exp -2011 dz论坛通杀 0DAY