刷題(3) 排序(1)

2021-09-25 12:32:49 字數 3422 閱讀 6043

(注意:n指資料規模;k指「桶」的個數;in-place指占用常數記憶體,不占用額外記憶體;out-place指占用額外記憶體)

冒泡,插入,歸併排序都是保證穩定性的,其他都不是

現代作業系統很少使用堆排序,因為它無法利用區域性性原理進行快取,也就是陣列元素很少和相鄰的元素進行比較和交換。

快速排序是最快的通用排序演算法,它的內迴圈的指令很少,而且它還能利用快取,因為它總是順序地訪問資料。它的執行時間近似為 ~cnlogn,這裡的 c 比其它線性對數級別的排序演算法都要小。

排序(2)總結

看到乙個很好的總結

工程排序中,有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個區,,小於,等於,大於主元的。

tips: 對於3向切分,我們時刻記住3點即可。

一直維護3個int,less是小於主元的最後乙個,more是大於主元的第乙個,cur是當前正在檢查的。

假如不傳主元,那麼我們把a[left]當作主元,那麼為了方便起見,把陣列從 a[left+1]開始算,但最後別忘了,要swap主元。假如傳了主元,那麼我們陣列從a[left]開始算,這次最後就不用swap了。

把 - - more交換過來的時候,cur不動,因為不知道換過來的是什麼貨色。

不傳主元的partition實現

先實現不傳主元,直接把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...