【C++】逆序对计数问题

还是分治的思想,解决方法利用了归并排序。具体可以看一下这篇博客

第三章:分治II - 不妨不妨,来日方长 - 博客园 (cnblogs.com)

C++代码如下,可以在VS直接运行。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int sort_merge_recursive(vector<int>& data,int left,1)">int right);
int sort_crossing_merge_recursive(vector<int mid,1)">void merge(vector< right);

 main()
{
    /*
        使用归并排序的思路来解决逆序数对计数的问题:还是分治的思想,分解成小问题、解决小问题、合并问题解。
    数组的分解跟归并排序里头的分解是一样的,都是二分,最后分到只剩单独一个元素。不同的是,归并排序直接
    比较分解之后子数组的大小,在合并的时候按照从小到大或者从大到小的顺序往新的容器里放就行了。
        逆序对问题,分解的步骤跟归并排序是一模一样的,在合并的过程中,两个子数组之间比较大小进行排序时,
    恰好可以判断子数组逆序对,条件在代码中后面注释了,就加了那一句代码;跟数组的最大子数组和不同的是,那个
    是求的左子数组、右子数组、跨中心数组中最大的一个,而求子数组逆序对,是把这三者相加。
    */

    vector<int> data = { 7,5,1)">6,1)">4};
    //获取序列元素个数
    int length = data.size();
    int left = 0;
    int right = 3int number=;
    vector<int> result;
    number = sort_merge_recursive(data,left,right);
    cout << "逆序对的个数是:"<< number << endl;
    for (int i = 0; i < length; i++)
    {
        cout << data.at(i) << "   ";
    }
}

 right)
{
    if (left >= right)
        return else
    {
        int mid = (left + right) >> 1;
         s1,s2,s3,s_end;
        s1 = sort_merge_recursive(data,mid);左子数组
        s2 = sort_merge_recursive(data,mid + 1,right);右子数组
        s3 = sort_crossing_merge_recursive(data,mid,1)">跨中心数组
        s_end = s1 + s2 + s3;求三个的和
        return s_end;
    }
}
int i = left;
    int j = mid +  temp;
    temp.resize(right - left + );
    int k = while (i <= mid && j <= right)
    {
        if (data.at(i) > data.at(j))
        {
            temp.at(k++) = data.at(j++);
            number += mid-i+1;这里是相比于归并排序增加的部分
        }
        
        {
            temp.at(k++) = data.at(i++);
        }
    }
    while (i <= mid)
    {
        temp.at(k++) = data.at(i++);
    }
    while (j <= right)
    {
        temp.at(k++) = data.at(j++int n = 0; n < k; n++)
    {
        data.at(left++) = temp.at(n);
    }

     number;
}

 

相关文章

计算斐波那契数 【lintcode】366 描述 查找斐波纳契数列中第 N 个数。 所谓的斐波纳契数列是指: 前2个...
1.二分搜索树特点:每个节点的键值大于左孩子; 每个节点的键值小于右孩子;以左右孩子为根的子树仍为二...
【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每...
一,单路快排1.测试用例: 2.归并排序: 3.优化时要用的插入排序: 4.单路快排实现: 图解单路快排: 5...
【程序9】 题目:一个数如果恰好等于它的因子之和,这个数就称为&quot;完数&quot;。例如6=1+2...
原理: 设两个有序的子序列(相当于输入序列)放在同一序列中相邻的位置上:array[low..m],array[m ...