確定分界點:mid = (l + r)/2 取中間數,分成[l,mid]和[mid,r]兩個區域。
將l[l,mid]和[mid,r]兩個區域進行遞迴排序。
歸併-將左右兩個有序的序列合併成乙個有序序列。給定你乙個長度為n的整數數列。
請你使用歸併排序對這個數列按照從小到大進行排序。
並將排好序的數列按順序輸出。
輸入格式
輸入共兩行,第一行包含整數 n。
第二行包含 n 個整數(所有整數均在1~109109範圍內),表示整個數列。
輸出格式
輸出共一行,包含 n 個整數,表示排好序的數列。
資料範圍
1≤n≤1000001≤n≤100000
輸入樣例:
5
3 1 2 4 5
輸出樣例:
1 2 3 4 5
//1、確定分界點 2、將左右區間進行遞迴排序 3、歸併-將兩個序列合二為一
#include using namespace std;
const int n = 1000010;
int q[n],temp[n];
int n;
void merge_sort(int q, int l, int r)
int main()
給定乙個長度為n的整數數列,請你計算數列中的逆序對的數量。
逆序對的定義如下:對於數列的第 i 個和第 j 個元素,如果滿足 i < j 且 a[i] > a[j],則其為乙個逆序對;否則不是。
輸入格式
第一行包含整數n,表示數列的長度。
第二行包含 n 個整數,表示整個數列。
輸出格式
輸出乙個整數,表示逆序對的個數。
資料範圍
1≤n≤1000001≤n≤100000
輸入樣例:
6
2 3 4 5 6 1
輸出樣例:
5
解析:分成三種情況。
左邊內部的逆序對數量:merge_sort(l,mid)
右邊內部的逆序對數量:merge_sort(mid+1,r)
在r區間第i個數(i屬於[mid+1,r])與l區間所有的數能構成逆序對的統計為si,所以逆序對數量總和為:s1+s2 +....+sm.
#include using namespace std;
typedef long long ll;
const int n = 100010;
int n;
int q[n],tmp[n];
ll merge_sort(int l, int r)
//掃尾
while(i <= mid) tmp[k ++] = q[i ++];
while(j <= r) tmp[k ++] = q[j ++];
//物歸原主
for (int i = l,j = 0;i <= r; i ++, j ++) q[i] = tmp[j];
return res;
}int main()
常用排序演算法 歸併排序
歸併排序 基本思想 先把陣列拆分,直到分成都只含有乙個元素的陣列,這樣兩兩合併,逐漸就可以得到已排序的字陣列,繼續合併直到合併成原來陣列長度為止。時間複雜度 o nlogn 空間複雜度 o nlogn 每一輪合併都需要n空間,共需要logn輪 第一輪是1 n 需要n個陣列,每個陣列長度為1 第二輪是...
常用演算法排序(04) 歸併排序
歸併排序是利用先遞迴進行分解,將乙個規模為 n nn 的問題分解成兩個規模為 n 2 n 2n 2 的問題,再不斷的繼續進行遞迴分解成最終規模為1 11的問題。然後再逐漸的從小規模結果進行合併,最終得到完整的結果。也即分而治之的思想。其 如下 原圖位址 歸併排序使用了空間換時間的方式,用乙個輔助陣列...
排序演算法 歸併排序
歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另...