描述
快速排序,是乙個很重要的排序演算法,當然其平均效能也比較高,他的思想我借鑑紀磊在啊哈演算法中的形容來描述。
在快排中,我們把待排序資料(如上圖)中的第乙個資料拿出來,稱他為基準,就是拿接下來的數字都跟他進行比較,如下圖所示,我們假設有兩個炮兵(此處紅五角星標識),乙個在資料的最左邊,乙個在資料的最右邊,剛開始我們右炮兵拿起他的數字7跟基準比,此數字大於基準6,所以炮兵往前走,9大於6,再往前走,3小於6,找到第乙個小於基準6的數字,把3放到基準原位置,然後左炮兵往後找,5、4、1、2小於6,炮兵一直往後走,直到兩個炮兵相遇,說明資料全部走完,所以基準數字找到了他的位置,就放到現在炮兵的位置,此時,6左邊的數字全部小於6,右邊的全部大於6,一次分割結束。
然後就是左邊數字後右邊數字分別再次進行分割,直到所有組內只剩乙個陣列代表排序結束。
後續過程不做詳細說明
**實現
此**實現是通過遞迴實現,我們把分割,呼叫分割的遞迴,分開實現,炮兵我們分別用low,high來標識,基準儲存在tmp變數中
一次劃分
//函式返回基準最終位置的下標,為下次劃分做準備
intpartition
(int
*arr,
int low,
int high)
//if
(arr[high]
< tmp)
//如果是找到小於基準的數字而跳出,將此數字放入原基準位置(其實說是上乙個空位比較恰當)
while
(arr[low]
<= tmp && low < high)
//左炮兵往後走,遇到大於基準的數字,跳出,同時判斷炮兵是否錯過
if(arr[low]
> tmp)
//找到比基準大的數字,放入空位
} arr[low]
= tmp;
//最終的空位將基準放入
return low;
//返回基準的位置
}
快排
void
quick
(int
*arr,
int low,
int high)
//o(logn),o(logn)
else
if(par +
1< high)
//判斷組內資料個數
}
時間複雜度、空間複雜度及穩定性
這裡我們一次劃分的時間複雜度是o(n),雖然是三層迴圈巢狀,但是實則遍歷了一遍資料,然後遞迴要進行logn次遞迴(本文log均為以二為底),所以快排的時間複雜度為o(n*logn)
這裡一次劃分的空間複雜度為o(1),遞迴呼叫logn次,所以快排的空間複雜度為o(logn)
因為出現跳躍式交換資料,所以並不穩定
進一步分析
當待排序資料完全有序,拿出第乙個資料作為基準,從後往前全部遍歷,每次都要如此,快排時間複雜度退化為o(n^2),並且退化為選擇排序
排序 快排與歸併
目錄歸併排序 1.隨機找到乙個基準數.2.將所有小於他的數放在左邊,所有大的數放在右邊.3.最後重複以上操作,直至各部分左右指標相遇.如gif所示,乙個無序的陣列3 5 8 1 2 9 4 7 6 把右端點作為基準數,然後左指標開始從左掃瞄,當遇 6 的數時停止,此時右指標就開始掃瞄,當遇到 6 的...
快排與堆排的比較 std sort實現分析
今天面試被問到了快排與堆排的應用場景,思考了一下只答上來了資料基本有序的情況下堆排優於快排以及topk問題選擇堆排,更進一步卻答不上來。後來發現其實堆排序和快速排序平均複雜度雖然都是o nlogn 但是在最差情況下堆排複雜度也是o nlogn 這一點比快排要好。但是稍微實驗一下就能發現,堆排序雖然平...
排序實現與分析 插排
思想 插入怕排序是一種簡單的排序方法,他的基本操作是將乙個資料插入到已有序的序列中,從而得到序列數加一的新的序列 插入排序中,我們先將最初始的有序序列數定為第乙個數字,即在下列資料中為1,從第二個開始,當前有序列為 1 5和有序序列從頭開始比較,發現5應該在1的後邊,所以新的有序序列為 1,5 然後...