欢迎使用CSDN-markdown编辑器

来源:互联网 发布:时尚杂志知乎 编辑:程序博客网 时间:2024/06/15 18:32

求排列的逆序数 (归并排序算法)
算法介绍:
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
这里写图片描述
归并排序算法原理:
先不断地进行二分,然后就两个两个相比较,就是分为两组,每组一个数,如果后面这个比前面的大,那就是一个逆序数对,然后就加一,并且将小的数字放在前面,于是合并,就得到了包含两个数的有序的一组数。接下来就是比较每组两个数的比较,如果第二组的第一个数大于第一组的第一个数,就加二,因为它比前面这组所有数都小。然后归并。以此类推。原则就是:如果后面这组数的某个数比前面这组的第i个数小,则逆序对数加上(mid-i+1)。
这里写图片描述
这里写图片描述

这里写代码片#include <stdlib.h>#include <stdio.h>void Merge(int sourceArr[],int tempArr[], int startIndex, int midIndex, int endIndex){    int i = startIndex, j=midIndex+1, k = startIndex;    while(i!=midIndex+1 && j!=endIndex+1)    {        if(sourceArr[i] >= sourceArr[j])            tempArr[k++] = sourceArr[j++];        else            tempArr[k++] = sourceArr[i++];    }    while(i != midIndex+1)        tempArr[k++] = sourceArr[i++];    while(j != endIndex+1)        tempArr[k++] = sourceArr[j++];    for(i=startIndex; i<=endIndex; i++)        sourceArr[i] = tempArr[i];}//内部使用递归void MergeSort(int sourceArr[], int tempArr[], int startIndex, int endIndex){    int midIndex;    if(startIndex < endIndex)    {        midIndex = (startIndex + endIndex) / 2;        MergeSort(sourceArr, tempArr, startIndex, midIndex);        MergeSort(sourceArr, tempArr, midIndex+1, endIndex);        Merge(sourceArr, tempArr, startIndex, midIndex, endIndex);    }}int main(int argc, char * argv[]){    int a[8] = {50, 10, 20, 30, 70, 40, 80, 60};    int i, b[8];    MergeSort(a, b, 0, 7);    for(i=0; i<8; i++)        printf("%d ", a[i]);    printf("\n");    return 0;}
0 0