數組中的逆序對
題目:在數組中的兩個數字如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。例如,有一個數組爲Array[0..n] 其中有元素a[i],a[j].如果 當i < j時,a[i]>a[j],那麼我們就稱(a[i],a[j])爲一個逆序對。在數組{7,5,6,4}中一共存在5對逆序對,分別是(7,6),(7,5),(7,4),(6,4),(5,4)。
輸入:{7,5,6,4}
輸出:5
思路:1、主要的思路就是利用歸併排序,先將數組分成每個數爲一個數組時
2、進一步,設置2個指針,P指針指向前一組的最後的一個元素,Q指針指向後一組的最後一個元素,在合併的時候判斷,前一組的最後的一個元素是否大於後一組的最後一個元素;
3、如果大於,則逆序對的數目要加上後一組中的所有元素;
4、如果小於或者等於,則將後一組的最後一個元素放在排好序的數組的最後一個元素中;另外將指針Q指針往前面移一位。
5、最後輸出逆序對的個數即可
/*
實現:數組中的逆序對
*/
#include<iostream>
#include<vector>
using namespace std;
int inverseNumber = 0;
void mergeArray(vector<int>& data, vector<int>& temp, int start, int mid, int end) {
int tempIndex = end;
int pIndex = mid;
int qIndex = end;
while (pIndex >= start && qIndex >= (mid + 1)) {
if (data[pIndex] > data[qIndex]) {
temp[tempIndex] = data[pIndex];
inverseNumber += qIndex - mid;
tempIndex--;
pIndex--;
}
else {
temp[tempIndex] = data[qIndex];
tempIndex--;
qIndex--;
}
}
while (pIndex >= start) {
temp[tempIndex] = data[pIndex];
tempIndex--;
pIndex--;
}
while (qIndex >= (mid + 1)) {
temp[tempIndex] = data[qIndex];
tempIndex--;
qIndex--;
}
}
void mergeSort(vector<int>& data, vector<int>& temp, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;
mergeSort(temp, data, start, mid);
mergeSort(temp, data, (mid + 1), end);
mergeArray(temp, data, start, mid, end);
}
}
int main(){
vector<int> number;
int temp;
do{
cin >> temp;
number.push_back(temp);
} while (cin.get() != '\n');
vector<int> temp;
temp.assign(number.begin(), number.end());
//這一塊加一個temp進去的話,就不用每次歸併的時候,都在開闢一個數組了。
mergeSort(number, temp, 0, number.size()-1);
for (int i = 0; i < number.size(); i++){
cout << number[i] << " ";
}
cout << endl;
cout << inverseNumber;
system("pause");
return 0;
}