(注意:n指資料規模;k指「桶」的個數;in-place指占用常數記憶體,不占用額外記憶體;out-place指占用額外記憶體)
冒泡,插入,歸併排序都是保證穩定性的,其他都不是排序(2)總結現代作業系統很少使用堆排序,因為它無法利用區域性性原理進行快取,也就是陣列元素很少和相鄰的元素進行比較和交換。
快速排序是最快的通用排序演算法,它的內迴圈的指令很少,而且它還能利用快取,因為它總是順序地訪問資料。它的執行時間近似為 ~cnlogn,這裡的 c 比其它線性對數級別的排序演算法都要小。
看到乙個很好的總結
工程排序中,有2個點:簡介當型別是自己定義的,用歸併排序,而不用快排,因為要保證穩定性,當型別是內建型別的時候,用快排,因為快排比歸併快(雖然複雜度一樣,但是係數小,而且額外空間複雜度小 歸併是o(n),快排是o(logn) 不是o(1),因為要記住那個斷點!!)
當要比較的數量小的時候(通常是小於60),用插入排序,因為這時候插入排序更快,雖然複雜度高,但因為係數小,所以數量小的時候,速度更快
快速排序是c.r.a.hoare於2023年提出的一種劃分交換排序。它採用了一種分治的策略,通常稱其為分治法(divide-and-conquermethod)。思想
該方法的基本思想是:先從數列中取出乙個數作為基準數。
分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。
再對左右區間重複第二步,直到各區間只有乙個數。
就是先搞定乙個數 把它放到正確的位置,再繼續搞。
時間複雜度:平均o(nlgn),最壞o(n^2)
最壞的情況是:
第一次從最小的元素切分,第二次從第二小的元素切分。
n+n-1+n-2+…+2+1 = n^2
最好的情況是:
每次都正好將陣列對半分,這樣遞迴呼叫次數才是最少的。複雜度為 o(nlogn)。
所以要把陣列隨機洗牌 確保有序的可能性賊小.
void quicksort(vector&vec, int left,int right)
swap(vec[less],vec[left]);
quicksort(vec,left,less-1);
quicksort(vec,more,right);
}
三向切分的partition。主要對有大量重複元素的陣列好使,這裡我們要把陣列分成3個區,,小於,等於,大於主元的。不傳主元的partition實現tips: 對於3向切分,我們時刻記住3點即可。
一直維護3個int,less是小於主元的最後乙個,more是大於主元的第乙個,cur是當前正在檢查的。
假如不傳主元,那麼我們把a[left]當作主元,那麼為了方便起見,把陣列從 a[left+1]開始算,但最後別忘了,要swap主元。假如傳了主元,那麼我們陣列從a[left]開始算,這次最後就不用swap了。
把 - - more交換過來的時候,cur不動,因為不知道換過來的是什麼貨色。
先實現不傳主元,直接把a[left]當主元的版本。
vectorpartition2(int a,int left,int right)
//等於主元,自然就是往前移動
else }
swap(a[less],a[left]); //注意,因為我們之前不把a[left]當做陣列的一部分,所以最後要交換主元。
vectorres;
res.push_back(less);
res.push_back(more);
return res;
}
傳主元版,通常用於只partition,不完全sort的題目
傳主元版,通常用於只partition,不完全sort的題目
注意和上面不傳主元的區別
void partition4(int a,int left,int right,int pivot)
else }
//注意最後不用swap
return vector 這裡就不寫了
}
有單向切分,和雙向切分之分
//基本快排 把第乙個元素當主元
寫快排要注意兩件事:1.指標不要越界 2.兩端出發的 最後哪個跟主元交換
void quicksort1(int a,int left,int right)
雙向掃瞄的partition
int partition1(int a,int left,int right)
//必須把主元跟p2交換,因為選的left做主元,而要達到的目的是主元的左邊都是小於等於主元的, 右邊都是大於等於主元的,而p1停在乙個大於等於主元的位置,p2停在乙個小於等於主元的位置,要是最後p1跟主元換,那最左邊就會是乙個大於等於主元的數,也就是可能大於,那就gg。
swap(a[left],a[p2]);
return p2;
}單向掃瞄的partition
int partition2(int a, int left, int right)
swap(a[left], a[small]);//注意需要交換!
return small;
}
//三數中值 當主元,且小陣列進行插入排序的優化快排
int median3(int a,int left,int right)
if(p1其實就是用棧來儲存下一次要排的兩個部分的兩個左右指標。
void quicksort(int *a, int left,int right)
if (j > k)}}
}//快排 面試版
void quicksort(vector& vec)
void quicksort(vector& vec,int l,int r){
if(l>=r)
return;
int pivot=vec[l];
int less=l;
for(int i=l+1;i<=r;++i){
if(vec[i]排序(2)總結
刷題1 排序1
學python有一段時間了,刷題試試。題 給定兩個字串 s 和 t 編寫乙個函式來判斷 t 是否是 s 的乙個字母異位詞。1.s anagram t nagaram 輸出true 2.s rat t car 輸出false 輸出true需要滿足的條件 1.字串的個數相等 2.元素一樣 故而我的想法是...
刷題筆記 二 排序
1 氣泡排序 將最大值放到末尾,一直縮小範圍到第一位 2 排序演算法的穩定性是指經過排序之後,能使值相同的資料保持原順序中的相對位置不變 解析 穩定性,就是指,不亂排序,很有規矩,能按照排序的演算法執行,相異的資料排序正確,相同的資料之間的前後關係也能不會錯位3 常見的內部排序有 並非所有排序都必須...
PAT刷題(二 排序)
大學期間專案做了不少,而在演算法題方面還是個小白。藉著考研機會,把pat甲級刷一遍,同時記錄一下心得。主要參考的是柳神的題解,略過了不會考或考的可能性很小的題。設定結構體儲存成績,分別排序計算排名就行啦。設定乙個exist陣列,用於快速定位特定id結構體的下標。通過設定乙個全域性變數flag,減少c...