冒泡排序就跟 “Hello World” 一樣,算是排序里第一個接觸的排序算法,因其排序過程像泡泡浮動的過程而得名。
思路
核心點在于,怎么完成一趟排序的過程(假設(shè)要求按從小到大排序),
- 從數(shù)組的第 0 位開始,和后一位進行大小比較。
- 如果大于后者,則交換一下,這樣大的值就在后面了。
- 接著繼續(xù)跟蹤著這個數(shù),再和后一位進行大小比較。
- 直到比到數(shù)組末尾結(jié)束,這樣一趟就完了。
- 那么第二趟也是一樣,從第 0 位開始,抓著它不放,依次兩兩比較,總共要進行 length - 1 趟。
以前學(xué)這塊的時候,代碼的實現(xiàn)有點死記硬背的感覺,現(xiàn)在代碼實現(xiàn)前,我會思考些關(guān)鍵步驟(就像上面這樣),有了關(guān)鍵步驟,寫起來和理解起來輕松很多。
優(yōu)化
上面的思路是最基礎(chǔ)的實現(xiàn),參考了書本,其實有兩處可以優(yōu)化改進,
- 如果數(shù)組是部分有序的,那么對有序的部分的比較就有點浪費了。而當(dāng)前趟的排序能知道下一趟排序的最終點的位置,所以可以優(yōu)化每趟排序比較的終點位置,即優(yōu)化步驟 4.
- 如果數(shù)組僅調(diào)整了幾個元素后就已經(jīng)完成有序,那么就沒必要再繼續(xù)排序了。也就是說如果進行一趟排序比較發(fā)現(xiàn)都不用調(diào)整,那么就說明數(shù)組已經(jīng)有序,此時就能省去一些趟次,即可以優(yōu)化步驟 5.
對于優(yōu)化點 1,可以通過記錄每次交換的元素下標(biāo)位置,開始下一趟排序?qū)Ρ葧r,用這個下標(biāo)位置作為循環(huán)判斷的終點。
對于優(yōu)化點 2,可以設(shè)置標(biāo)記位,排序?qū)Ρ乳_始前認為已經(jīng)有序,當(dāng)發(fā)生元素交換時則置為 false,表示亂序,當(dāng)一趟結(jié)束,如果仍然有序就可以結(jié)束整個排序,輸出結(jié)果了。
雞尾酒排序
這個排序算法還是第一次知道,核心就是將冒泡排序中的一趟排序?qū)Ρ葓?zhí)行兩遍,但是兩遍的方向不同,例如第一次從位置 0 開始,那么第二次就是從位置 length - 1 開始,這么兩遍算一趟。
這么來算的話,頂多需要進行 length / 2 趟。
這個算法的優(yōu)勢在于對于基本有序,但又是和要求的順序是反的的情況下也能節(jié)省時間,例如要求從小到大,可偏偏數(shù)組是 {1,9,8,7,6,5,4,3,2},這時如果兩個方向進行排序?qū)Ρ染湍芎芸旖鉀Q。
實現(xiàn)完這個我在想,既然可以兩遍,那是不是也能四遍一起?大概想了下應(yīng)該是可行的,不過我沒有測試,沒有本質(zhì)區(qū)別,可能最多就是省點時間,就像奶茶的中杯和大杯。
代碼
github 地址:找代碼里的 bubbleSort 和 cocktailSort