归并排序求逆序数
时间:2020-04-18
本文章向大家介绍归并排序求逆序数,主要包括归并排序求逆序数使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
- 问题:求逆序数。
- 算法:归并排序。
归并排序是分治法(分而治之)的一种典型应用,应用递归的思想,自顶向下思考:先假定mergesort()可以将一个乱序的数组排好序,因此就可以开始"分"(将一个数组平均分成两部分),再"治"(分别对前后部 分调用mergesort()使它们有序),最后再写一个合并子函数Combine(),它可以将两个有序的数组合并,Combine()实现起来比较容易.只需要管理两个指针,分别指向两个子数组的开头,开辟新内存保存中间结 果,遍历完两个数组就可以完成,时间是Θ(n).
假定n个元素的数组调用mergesort()需要时间T(n).因此,T(n)=2T(n/2)+Θ(n).由主定理可知:T(n)=Θ(nlogn).归并排序算法的时间复杂度是Θ(nlogn),空间复杂度是Θ(n).
代码如下:
1 # include <cstdio> 2 # include <iostream> 3 # include <algorithm> 4 5 using namespace std; 6 7 int arr[100]; 8 int temp[100]; 9 int number = 0; 10 //合并函数。 11 void Combine(int left,int middle,int right){ 12 int i = left; 13 int j = middle+1; 14 int k = left; 15 while (i <= middle && j <= right){ 16 if(arr[i] <= arr[j]){ 17 temp[k++] = arr[i++]; 18 }else{ 19 number+=middle-i+1;//1.归并排序求逆序数核心,记录逆序数对数。 20 temp[k++] = arr[j++]; 21 } 22 } 23 while(i <= middle){ 24 temp[k++] = arr[i++]; 25 } 26 while(j <= right){ 27 temp[k++] = arr[j++]; 28 } 29 for(int m=left; m<=right; m++){ 30 arr[m] = temp[m]; 31 } 32 return; 33 } 34 35 void mergersort(int left,int right){ 36 if(left < right){ 37 int middle = left + (right-left)/2; 38 mergersort(left,middle); 39 mergersort(middle+1,right); 40 Combine(left,middle,right); 41 } 42 return; 43 } 44 int main(){ 45 int n; 46 while( scanf("%d",&n)!= EOF){ 47 for(int i=0; i<n; i++){ 48 scanf("%d",&arr[i]); 49 } 50 mergersort(0,n-1); 51 for(int j=0; j<n; j++){ 52 printf("%d ",arr[j]); //排序后的数组。 53 } 54 55 printf("\n"); 56 printf("%d\n",number); 57 } 58 }
当然求逆序数也可以暴力求解,直接双重循环,此时算法复杂度为O(n2),废话不多说代码如下:
1 # include <cstdio> 2 # include <iostream> 3 4 using namespace std; 5 int number; 6 int arr[100]; 7 int main (){ 8 int n; 9 while( scanf("%d",&n) != EOF){ 10 number=0; 11 for(int k=0; k<n; k++){ 12 scanf("%d",&arr[k]); 13 } 14 for(int i=0; i<n; i++) 15 for(int j=i; j<n; j++){ 16 if(arr[i]>arr[j]){ 17 number++;//记录逆序数对数 18 } 19 } 20 printf("%d\n",number); 21 22 } 23 }
显然暴力求解代码量少,但是归并排序的效率更高。
原文地址:https://www.cnblogs.com/jhwlxx/p/12726896.html
- bootstrap + requireJS+ director+ knockout + web API = 一个时髦的单页程序
- Gym 100952E&&2015 HIAST Collegiate Programming Contest E. Arrange Teams【DFS+剪枝】
- Gym 100952H&&2015 HIAST Collegiate Programming Contest H. Special Palindrome【dp预处理+矩阵快速幂/打表解法】
- Gym 100952G&&2015 HIAST Collegiate Programming Contest G. The jar of divisors【简单博弈】
- Gym 100952F&&2015 HIAST Collegiate Programming Contest F. Contestants Ranking【BFS+STL乱搞(map+vector)+
- Gym 100952D&&2015 HIAST Collegiate Programming Contest D. Time to go back【杨辉三角预处理,组合数,dp】
- Gym 100952B&&2015 HIAST Collegiate Programming Contest B. New Job【模拟】
- 51 Nod 1008 N的阶乘 mod P【Java大数乱搞】
- 【AlphaGo Zero 核心技术-深度强化学习教程代码实战06】给Agent添加记忆功能
- Gym 100952A&&2015 HIAST Collegiate Programming Contest A. Who is the winner?【字符串,暴力】
- [开源,学习,分享]UWP第三方简书客户端分享
- HDU 1024 Max Sum Plus Plus【动态规划求最大M子段和详解 】
- 51 Nod 1057 N的阶乘【Java大数乱搞】
- 2017 Multi-University Training Contest - Team 1 1011&&HDU 6043 KazaQ's Socks【规律题,数学,水】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法