利用归并排序求逆序数
来源:互联网 发布:c 语言课程主要内容 编辑:程序博客网 时间:2024/06/05 20:49
假设A[1…n]是一个有n个不同元素的数组,若i < j 且 A[i] > A[j],则对偶(i, j)称为A的一个逆序对。例如,对于数组[2, 3, 8, 6, 1],它的所有逆序对为(1, 5),(2, 5),(3, 4),(3, 5),(4, 5),共有5个逆序对,所以逆序数为5。
当数组中元素数量较少时,我们可以通过手工计算数组的逆序数;但是如果数组中元素比较多时,手工计算比较麻烦,我们可以利用归并排序来计算数组的逆序数。归并排序的思路是将数组A[1…n]分成A[1…mid]和A[mid+1…n]分别进行归并排序,然后再将这两个排好序的数组合并。在合并的过程中(假设按从小到大排序,1 <= i <= mid 且 mid + 1 <= j <= n),当A[i] <= A[j]时,没有逆序对;当A[i] > A[j]时,A[1…mid]中比A[i]大的数都比A[j]大,又因为A[j]要放在A[i]前面,所以当前的逆序数就等于mid - i + 1。把所有归并过程中的逆序数加起来就是原数组的逆序数。
//归并排序求逆序数的代码 static int merge(int* arr, int low, int mid, int high) { int cnt = 0; int len = sizeof arr / sizeof *arr; int tmp[len]; //将数组arr中的元素存到tmp中 for(int k = low;k <= high;k++) tmp[k] = arr[k]; for(int k = low, i = low, j = mid + 1;k <= high;k++){ //左半边元素用完了 if(i > mid) arr[k] = tmp[j++]; //右半边元素用完了 else if(j > high) arr[k] = tmp[i++]; //右边元素小于左边的元素 else if(tmp[j] < tmp[i]) arr[k] = tmp[j++],cnt += mid - i + 1; //左边的元素小于右边的元素 else arr[k] = tmp[i++]; } return cnt; } int merge_sort(int* arr, int low, int high) { int ans = 0; if(low < high){ int mid = low + (high - low) / 2; ans += merge_sort(arr, low, mid); ans += merge_sort(arr, mid + 1, high); ans += merge(arr, low, mid, high); } return ans; }
阅读全文
0 0
- 利用归并排序求逆序数对
- 利用归并排序求逆序数
- 利用归并排序求逆序数对
- 利用归并排序求逆序数
- 归并排序,求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- 归并排序求逆序数
- 求逆序数(归并排序)
- 归并排序求逆序数
- 想起了一道面试题:根据输入的数字a打印2a-1项的先递增到a项再递减的*行。
- Python学习1-安装和Hello world
- 关于布局的Demo
- 2017.7.03 学习记录 Java与MySql的连接
- 字符集GBK和UTF8的区别
- 利用归并排序求逆序数
- HDU5969-最大的位或
- 基础知识记录:Activity生命周期与Fragment生命周期
- 状态栏1---状态栏响应滚动事件
- linux下gzip,bzip2,tar,zip,rar压缩与解压缩命令总结
- Springboot整合mybatis出现无法注入mapper接口的问题处理
- Retrofit(一)、Retrofit+OkHttp实现简单的Get与Post请求
- 3442: 学习小组
- const与指针、成员函数、#define