陣列a中的乙個逆序對(a[i], a[j])是ia[j]。平凡的方法是遍歷所有數對,時間複雜度為o(n^2),利用歸併排序的思想可以降至o(nlgn)。
#include #include #include #include #include using namespace std;
//平凡的計算逆序數的方法
//比較陣列中的所有c(n, 2)個數對
//時間複雜度o(n^2)
int trival_inverse(const vector&a, int first, int last)
}return count;
}//當[first, mid)和[mid, last)有序時計算陣列的逆序對數目
//左半部分和右半部分均已有序,無逆序對
//每次比較固定右半段某個數,找出左半段中所有能構成逆序對的數
//當first <= i < mid, mid <= j < last時
//若a[i] > a[j]
//則左半部分a[k](k>=i)均與a[j]構成逆序對,共mid - first - i個
//左半部分a[k](k&a, int first, int mid, int last)
else
}return count;
}//結合歸併排序,將陣列分為兩段,左右兩段分別排序並計算各自的逆序對數目c1, c2
//這不會影響左右兩段一起產生的逆序對數目c0,再計算出c0,總的逆序對數目即為c1 + c2 + c0
int merge_inverse(vector&a, int first, int last)
int main()
int beg, end;
beg = clock();
printf("n=%d\n", n);
printf("%d\t", trival_inverse(a, 0, a.size()));
end = clock();
printf("time:%d\n", end - beg);
beg = clock();
printf("%d\t", merge_inverse(a, 0, a.size()));
end = clock();
printf("time:%d\n", end - beg);
n *= 10;
}return 0;
}
執行結果如下:
歸併排序法計算逆序對數
今天遇到求逆序對的問題,經過一番思索之後,特意來總結一下。因為也學習到了很多方法,以前自己一些百思不得其解的問 題也有了解答。分析 題目中說使用插入排序,也就是在排序過程中計算交換的次數,按照插入排序的原理,先定第乙個,再定前兩個的順序,以此類推,只要交換了,我的次數就加一,但實際上,我們一直按照原...
歸併排序求逆序對數
參考部落格 歸併排序求逆序對數 include include include includeusing namespace std 歸併排序是借助乙個輔助陣列來進行排序 int ans 0 void merge sort int a,int l,int r,int t a是原陣列,t是輔助陣列 i...
歸併排序求解逆序對數
定義 逆序對就是對於ia j 這樣的數對在序列中的個數。求解方法 歸併排序是採用分治的思想劃分數列,然後將兩路有序的數列合併。通過劃分和合併的遞迴呼叫來完成排序。在合併的過程中,兩個數列中的元素的相對位置不會發生改變 這裡只是前後關係 而且如果後乙個數列b中某個元素b在需要先放入 優先於前乙個數列a...