快排 歸併排序

2021-10-18 04:18:07 字數 3732 閱讀 5804

二、 歸併排序

遞迴+分治的思維

(分治)

確定分界點 (我們下面以中間值q[l+r >> 1] 為分界點, 理論上任何點作為分界點都可)

調整區間: <= x 的在左邊, >= x的在右邊(兩個區間)

遞迴: 遞迴處理左右兩段

原題鏈結

題目描述

給定你乙個長度為n的整數數列。

請你使用快速排序對這個數列按照從小到大進行排序。

並將排好序的數列按順序輸出。

輸入格式

輸入共兩行,第一行包含整數 n。

第二行包含 n 個整數(所有整數均在1~109範圍內),表示整個數列。

輸出格式

輸出共一行,包含 n 個整數,表示排好序的數列。

資料範圍

1≤n≤100000

#include

#include

using namespace std;

const

int n =

100010

;int n;

int a[n]

;void

quick_sort

(int l,

int r)

quick_sort

(l, j)

;quick_sort

(j +

1, r);}

intmain

(void

)

題目鏈結

題目描述:

給定乙個長度為n的整數數列,以及乙個整數k,請用快速選擇演算法求出數列從小到大排序後的第k個數。

輸入格式

第一行包含兩個整數 n 和 k。

第二行包含 n 個整數(所有整數均在1~109範圍內),表示整數數列。

輸出格式

輸出乙個整數,表示數列的第k小數。

#include

#include

using namespace std;

const

int n =

100010

;int n, k;

int a[n]

;void

quick_sort

(int l ,

int r)

if(j >= k)

quick_sort

(l, j)

;else

quick_sort

(j +

1, r);}

intmain

(void

)

補充: 若陣列並非全域性變數,快排函式需要傳入引數+1

//不是全域性變數時

void

quick

(int arr,

int l,

int r)

//有遞迴的終點,沒有其他特殊需求的情況下不需要有條件的遞迴。

quick

(arr, l, j)

;//排左

quick

(arr, j +

1, r)

;//排右

}

確定分界點,以整個陣列的中間為分界點(下標中間值),分為左邊,右邊mid = (l + r) / 2兩區間

遞迴排序[l, mid] [mid + 1, r]兩區間

歸併—合二為一,兩個有序的序列合成乙個有序序列

題目鏈結

題目描述:

給定你乙個長度為n的整數數列。

請你使用歸併排序對這個數列按照從小到大進行排序。

並將排好序的數列按順序輸出。

輸入格式

輸入共兩行,第一行包含整數 n。

第二行包含 n 個整數(所有整數均在1~109範圍內),表示整個數列。

輸出格式

輸出共一行,包含 n 個整數,表示排好序的數列。

#include

#include

using namespace std;

const

int n =

100010

;int n;

int a[n]

, tmp[n]

;void

merge_sort

(int l,

int r)

while

(i <= mid) tmp[k ++

]= a[i ++];

while

(j <= r) tmp[k ++

]= a[j ++];

//把輔助陣列中的值複製回到原陣列中

for(

int i = l, j =

0; i <= r; i ++

, j ++

) a[i]

= tmp[j];}

intmain

(void

)

題目鏈結

題目描述:

給定乙個長度為n的整數數列,請你計算數列中的逆序對的數量。

逆序對的定義如下:對於數列的第 i 個和第 j 個元素,如果滿足 i < j 且 a[i] > a[j],則其為乙個逆序對;否則不是。

輸入格式

第一行包含整數n,表示數列的長度。

第二行包含 n 個整數,表示整個數列。

輸出格式

輸出乙個整數,表示逆序對的個數。

1≤n≤100000

講所有逆序對分為三大類:

兩數同時出現在左半邊: merge_sort(l, mid);

兩數同時出現在右半邊: merge_sort(mid + 1, r);

一左一右:sj = r - mid + 1

可以思考歸併過程,第二個序列的下標為j 的值填充時, 第乙個序列此時指向的下標為 i, 那麼 第乙個序列中 i – mid 一定大於 第二個序列中下標為 j 的數 ,

當我們不斷劃分成小區間時,我們就把1,2兩種情況化成第三種情況了。

乙個小細節

當原陣列為降序時,此時逆序對數量最多

第乙個數: n - 1個 逆序對

第二個數: n - 2個

…… 1 個

相加時,n(n - 1) / 2個 大概 n ^ 2 / 2; 5 * 10 ^ 9 > int

#include

#include

using namespace std;

typedef

long

long ll;

ll sum;

const

int n =

100010

;int n;

int a[n]

, tmp[n]

;long

long

merge_sort

(int l,

int r)

}while

(i <= mid) tmp[k ++

]= a[i ++];

while

(j <= r) tmp[k ++

]= a[j ++];

for(

int i = l, j =

0; i <= r; i ++

, j ++

) a[i]

= tmp[j]

;return res;

}int

main()

快排和歸併排序講解

快速排序 歸併排序 找陣列的最後乙個數字,假設為number,然後number為標準,調整陣列 陣列左邊是小於number的數,中間是等於number的數,右邊是大於number的數,然後對小於number的部分繼續進行上述操作,對大於number的部分繼續進行上述操作。這是普通的快速排序,和資料的...

演算法 歸併排序與快排

歸併排序是另一種不同的排序方法,因為歸併排序使用了遞迴分治的思想,所以理解起來比較容易。其基本思想是,先遞迴劃分子問題,然後合併結果。把待排序列看成由兩個有序的子串行,然後合併兩個子串行,然後把子序列看成由兩個有序序列。倒著來看,其實就是先兩兩合併,然後四四合併。最終形成有序序列。空間複雜度為o n...

單鏈表排序 快排 歸併排序

題目描述 給定乙個亂序的單鏈表的頭節點,對該鍊錶中的節點進行排序 要求時間複雜度為o nlgn 空間複雜度為o 1 分析 由於題目要求時間複雜度我o nlgn 因此選擇排序和插入排序可以排除。在排序演算法中,時間複雜度為o nlgn 的主要有 歸併排序 快速排序 堆排序。其中堆排序的空間複雜度為 n...