在說排序前,先說說分治吧,顧名思義,分治即將較大的問題分解成幾個較小的問題,並對較小問題逐一求解。其具備以下兩個特點
1.時間複雜度為所有子問題複雜度之和
2.一般情況下多分為兩部分,如二分答案(有時結合遞迴使用)
注意:以下排序都以從小到大為例
進入正題,歸併也體現著分治的特點(子模組),假設有兩個有序的陣列 a b 並取乙個新的空陣列c ,每次從a與b中取當前位置的兩個數中較小的元素放入c中(取法看不懂沒事,可在**中體會),直至a,b都空,這樣c得到的即是乙個有序的數列。
基於上述思想 分治即將原來的的數列分為前後兩段(假設前後分為為a,b) 並對其合併處理,很明顯,這麼做的前提即a,b都要是有序的,那麼現在的問題即轉移到了怎麼將a,b變成有序上來,這時我們發現,對a,b的排序實質上與原陣列的排序無異,那麼此時可以通過遞迴實現每個模組的排序過程。因此排序的基本過程如下:
1 確定三根指標,分別指向數列的最左邊(left),最右邊(right)以及中間(mid)
2 遞迴呼叫該函式 使得子模組有序
3 將left-mid與mid+1-right合併
附上基本模板(做了細微的優化)
int a[
10001
],b[
10001];
/*實際上能處理的資料遠不止這些
歸併具備很高的演算法效率*/
void
mergesort
(int left,
int right)
注:歸併是穩定的排序演算法,在區域性有序的題目中可以有較好的效果(可見noip2023年真題瑞士輪)
快速排序是對冒泡的優化改進,由c. a. r. hoare在2023年提出,應用較廣泛.
與歸併相同,快速排序同樣對乙個數列進行了分割,並以中間元素(此後稱之為a[mid])為準,列舉前後兩段的元素,將比a[mid]小的部分放在前半段,比a[mid]大的部分放在後半段,此過程可通過定位與交換元素實現,交換完成後就保證了前半段整體小於後半段,再遞迴使用函式,對前後兩段的元素排序,直至小段長度為小於等於1即完成排序。基本步驟如下:
1.設需要排序的陣列為a,確定三根指標,指向最左(left),最右(right),中間位置(mid);
2.列舉i-mid找到第乙個比啊a[mid]大的位置並停止,同理,使j指向第乙個比a[mid]小的位置
3.交換i,j 指向的元素
4.重複上述過程直至i,j交叉(分配完畢)
5,遞迴呼叫函式對前後兩個子模組排序
附上標準模板:
void
qsort
(int left,
int right)}if
(lqsort
(l,j)
;//如果此時左模組的右邊界變成了j
if(iqsort
(i,r)
;//此時右模組的左邊界變成了i
}
分治演算法排序(C 版)
分治排序 把乙個陣列分成兩個陣列,然後在把這兩個陣列再各自分成兩個陣列,直到陣列有兩個數,然後比較這兩個數,並且合併,排序。就是上面這個樣子 的。不說了上 c 版 name 分治演算法 time 15 8 9 14 25 environment ubuntu 14.04,sublime text 3...
STL在排序演算法中的應用小例
題目 1 對整形資料組按照和指定整數的差值大小進行排序,按照差值公升序排列返回。輸入 num 整型陣列 value 指定的整數 返回 按照公升序返回整型陣列,排序按照各個整數和指定整數的差值大小 示例 輸入 num value 5 sub num 取大的減小的 返回 實現 include stdaf...
分治演算法的簡單應用
1.要求2n個數的中位數,採用分治策略。每次劃分後,都會去掉一半的數,只剩原來一半的數。遞推關係式為 t n t n 2 o 1 由master定理,可得時間複雜度為o logn include include define n 1000000 using namespace std int a n...