本篇文章僅介紹順序表(即陣列)的n種常見的排序演算法,以後遇到有意思的演算法還會持續補充。其他資料結構的排序不在本文討論範圍內。本文所有演算法由c#**實現,將32位有符號整數int型別(取值範圍[-2^31,2^31-1])陣列按從小到大排序。
排序演算法分類大致如下(不全,有時間就慢慢補充吧)
2023年7月6日更新
內部排序:排序期間所有元素均在記憶體裡。
外部排序:排序期間元素無法全部存放在記憶體中,必須在排序的過程中根據要求不斷地在記憶體,外存中移動。
在正式討論排序演算法前,我們先思考三個問題:
問題一:如何交換兩個數的值?
方法一:通過臨時變數。另外通過stack和queue就不說了。
方法二:通過算數運算。相比方法一,不用開闢臨時變數的記憶體,但是多了幾步算數運算的過程。通過算數運算分兩種:一種是加減,一種是乘除。其中加減運算通用性較高,其次是乘除運算,因為乘除無法對0進行操作,且比加減運算更容易超出資料型別的最大值限制。下面以加減運算為例,展示**及過程。如果要換為乘除運算,將「+」替換為「*」,「-」替換為「/」即可。
加減運算交換圖示
方法三:通過異或運算。先回顧下c#裡的四個邏輯運算子。
以上是四個邏輯運算子的二進位制解釋,最簡單的方式是下面韋恩圖的解釋。
韋恩圖異或交換圖示
問題二:如何隨機打亂乙個陣列?
這個問題還是很有意義的,比如在遊戲裡玩家**前,正面隨機順序展示若干張**卡。
問題三:什麼是排序的穩定性?
穩定與不穩定的區別就是相同值的元素排序後是否保留排序前的先後順序,保留則為穩定。假如只有兩個糖果分別分給考試成績前兩名的同學,他們的區別就是下面這樣。。。
第一種排序:氣泡排序
初學程式設計的人可能接觸到的第乙個排序演算法就是氣泡排序。所謂的「泡」指的是每一次外層迴圈所移動到陣列後面的乙個最大的值。氣泡排序對陣列的重新排列是從末尾開始,即按從後往前的方向,將陣列元素從大到小排列。下面展示了一種未優化的氣泡排序演算法。
上面的排序還有許多可優化的點,下面結合**展示一種優化後的氣泡排序演算法。這裡只展示相對通用的優化方式,如果有相對具體的排序資料模型,就可以深度定製優化方案。本文其他排序演算法均展示相對通用、易於理解的寫法。
每次外迴圈得到的橙色數字,就是「泡」
氣泡排序的時間複雜度由比較和移動(即交換)的次數決定,下面展示優化的效果
第二種排序:直接插入排序
直接插入排序的核心就是維護乙個開頭開始的按從小到大排好的區域性陣列(區域性陣列初始元素為0號索引),每往後遍歷乙個新元素,就考慮將之插入到區域性陣列中,迴圈往復,使之充滿整個陣列。
第三種排序:簡單選擇排序
簡單選擇排序的核心也是維護乙個開頭開始的按從小到大排好的區域性陣列(不過這個區域性陣列沒有初始元素),每次遍歷後半部分陣列,找出最小的紅色數加到區域性陣列的最後面。從圖中兩個5可以看出,簡單選擇排序是不穩定排序。
第四種排序:快速排序
施工中。。。
php陣列按ascii排序 php 中英文陣列排序
header content type text plain charset utf 8 shuffle arr 打亂陣列 collator sort collator create zh cn arr usort arr,function a,b usort arr,function a,b ec...
陣列排序(按陣列中字典的某一鍵值對)
1。普通陣列排序 nsmutablearray arr nsmutablearray arraywithobjects 0 8 6 1 nil nsarray sortedarray arr sortedarrayusingcomparator nscomparisonresult id obj1,...
Python字典按值排序的方法
python字典按值排序的方法 法1 預設公升序排序,加reverse true指定為降序排序 sorted的結果是乙個list dic1sortlist sorted dic1.items key lambda x x 1 reverse true 法2 import operator sorte...