归并排序 MergeSort

逆序对数

时间限制:1 秒 空间限制:65536 KB
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。
如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。

Input
第1行:N,N为序列的长度(n <= 50000)
第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9)

Output
输出逆序数

Input 示例
 4
2
4
3
1

Output 示例
4

从后往前比较,前面的数每大于后面的数一次加1,但是直接计算会超时。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[50005];
int main()
{
    int n,sum=0;
    scanf("%d",&n);
    for(int i=0; i<n; i++)
        scanf("%d",&a[i]);
    for(int i=n-1; i>0; i--)
        for(int j=0; j<i; j++)
        if(a[j]>a[i])
          sum++;
        printf("%d\n",sum);
    return 0;
}

于是就有了 归并排序算法:

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide
and Conquer)的一个非常典型的应用。值得注意的是归并排序是一种稳定的排序方法。

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序,称为2-路归并。

算法描述:

归并操作的工作原理如下:

第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置

第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

重复步骤3直到某一指针达到序列尾

将另一序列剩下的所有元素直接复制到合并序列尾

时间复杂度为O(nlogn)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[50005],b[50005];
int mergeSort(int low,int high)
{
    if (low == high)
        return 0;
    int count=0;
    int mid=(low+high)/2;
    count = mergeSort(low,mid)+mergeSort(mid+1,high);
    int i=low,j=mid+1,k=low;
    while(i<=mid && j<=high)
        if(a[i]<=a[j])
            b[k++]=a[i++];
        else
        {
           b[k++]=a[j++];
           count += (mid - i + 1);
        }
    while(i<=mid)
        b[k++]=a[i++];
    while(j<=high)
        b[k++]=a[j++];
    for(i=low; i<=high; i++)
        a[i]=b[i];
    return count;
}
int main()
{
    int N,i;
    scanf("%d", &N);
    for (i = 0; i < N; ++i)
        scanf("%d", &a[i]);
    cout<<mergeSort(0,N-1);
    return 0;
}
时间: 2024-11-01 15:29:02

归并排序 MergeSort的相关文章

归并排序MergeSort

   归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.值得注意的是归并排序是一种稳定的排序方法.速度仅次于快速排序,为稳定排序算法,一般用于总体无序,但是各子项相对有序的数列.若将两个有序表合并成一个有序表,称为二路归并. 1.算法思想         比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1:否则将第二个有序表中的元素a[j]复制到r

深入排序算法的多语言实现

 1 排序的基本概念 排序: 所谓排序,就是要整理文件中的记录,使之按关键字递增(或递减)次序排列起来.其确切定义如下: 输入:n个记录R1,R2,-,Rn,其相应的关键字分别为K1,K2,-,Kn. 输出:Ril,Ri2,-,Rin,使得Ki1≤Ki2≤-≤Kin.(或Ki1≥Ki2≥-≥Kin). 排序的稳定性:当待排序记录的关键字均不相同时,排序结果是惟一的,否则排序结果不唯一.在待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,该排序方

C/C++中的经典排序算法总结

C/C++中的经典排序算法总结 在C/C++中,有一些经典的排序算法,例如:冒泡排序.鸡尾酒排序或双向冒泡排序(改进的冒泡排序).选择排序.直接插入排序.归并排序.快速排序.希尔排序和堆排序等等.下面对这些排序算法进行一一解析并给出示例代码以共享之. 1.冒泡排序 冒泡排序是最基本的排序算法,之所以称之为冒泡排序是因为在冒泡排序的过程中总是大数往前放,小数往后放,相当于气泡上升. 冒泡排序的基本原理是:依次比较相邻的两个数,将大数放在前面,小数放在后面. 影响冒泡排序算法性能的主要部分就是循环和

JavaScript排序,不只是冒泡

做编程,排序是个必然的需求.前端也不例外,虽然不多,但是你肯定会遇到. 不过说到排序,最容易想到的就是冒泡排序,选择排序,插入排序了. 冒泡排序 依次比较相邻的两个元素,如果后一个小于前一个,则交换,这样从头到尾一次,就将最大的放到了末尾. 从头到尾再来一次,由于每进行一轮,最后的都已经是最大的了,因此后一轮需要比较次数可以比上一次少一个.虽然你还是可以让他从头到尾来比较,但是后面的比较是没有意义的无用功,为了效率,你应该对代码进行优化. 图片演示如下: 代码实现: function bubbl

Hive中 分区表和桶

Hive分区表 在hive Select 查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作.有时候只需要扫描表中关心的一部分数据,因此建表时引入了partition概念.分许表指的是在创建表时指定的partition的分区空间. Hive可以对数据按照某列或者某些列进行分区管理,所谓分区我们可以拿下面的列子进行解释. 当前互联网应用每天都要存储大量的日志文件.几G.十几G甚至更大都是有可能的.存储日志,其中必然有个属性是日志产生的日期.在产生分区时,就可以按照日志产生的日期列进行划分.把

多线程-我这样是否对同一个对象进行了排序(小猿一只,评论勿留情)

问题描述 我这样是否对同一个对象进行了排序(小猿一只,评论勿留情) import java.util.Random; public class MergeSort implements Runnable{ public void run() { int[] a = new int[100000]; Random p = new Random(); //产生随机数 for(int i=0;i<100000;i++) a[i] = p.nextInt(10000); //计时 //long star

jquery 动态演示各种排序实例代码

提示:您可以先修改部分代码再运行 <!doctype html> <html> <head> <meta charset="utf-8" /><title>快速排序(quicksort)的javascript实现-动画演示</title> <link href="css.css" type="text/css" rel="stylesheet" /&

java实现归并排序和树形排序(锦标赛制):java字符串分隔或的形式

String[] b=str.split("query|,");//query分隔或者逗号分隔 归并排序,递归实现 public class MergeSort2 { // 对data数组中的 [a,b) 区间的数据进行归并排序, // 排序结束后,[a,b)间数据处于升序有序状态 static void mergeSort(int[] data, int a,int b) { if (a >= b) return; int mid=(a+b)/2;//拆分排序 mergeSor

数据结构之归并排序(merging sort) 详解

归并排序(merging sort): 包含2-路归并排序, 把数组拆分成两段, 使用递归, 将两个有序表合成一个新的有序表. 归并排序(merge sort)的时间复杂度是O(nlogn), 实际效果不如快速排序(quick sort)和堆排序(heap sort), 但是归并排序是稳定排序, 而快速排序和堆排序则不是. 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1