資料結構 氣泡排序以及其優化

2021-08-11 01:45:32 字數 2057 閱讀 8475

我以前一直對冒牌排序不以為然,作為最容易寫出來的排序.直到前兩天我被人問到乙個問題,讓我把普通的氣泡排序最好的時間複雜度

優化到o(n).

當然氣泡排序最壞時間複雜度o(n^2)這個沒有辦法改變.我們只能盡量優化它的過程讓它少走幾次迴圈.

其實仔細做起來,我

在寫程式有時候還是太片

面了不能夠考慮到最優的效率,只是單純的實現功能,這樣不好. 好了進入正題,我們首先了解氣泡排序的過

程和原理.

所謂的氣泡排序將被排序的記錄陣列a[1...n] 垂直排列,每乙個記錄a[i]看作重量為r[i].key的氣泡.根據輕氣泡不能在重氣

泡之下的原則,從下往上

掃 描陣列a.凡掃瞄到違反本原則的輕氣泡,就讓他往上漂浮, 如此反覆進行。知道最後任何兩個氣泡都是輕者在上

,重者在下為止為止,我這裡使用一

張圖幫我們理解.  該圖為冒牌排序的過程.

動態過程:

這個排序的基本**非常容易實現如下所示:

void popsort(int* a, size_t n)

} }}

它的時間複雜度非常容易理解:o(n^2). 但是我們仔細看看上面的圖.從第六次迴圈的時候整個陣列其實已經排好序了,後面的迴圈其實

都是多餘的操作

我們程式設計師是乙個追求效率的東西,所以呢我們要想辦法解決掉這個問題, 這個時候我有這麼乙個想法,我們可不可

以這麼想. 如果我迴圈一趟沒有發

生交換,那麼這個陣列整個就排好序了.這裡認真想,如果你一趟下來下來沒有交換任何資料,說明你

這個陣列的每乙個位置a[i]有序啊.所以我們可以使用乙個標記變數,然後如果交換了就改變標記變數的值.如果內

迴圈一趟出來,標記變數沒有變化那就是排好序了.**實現:

//外迴圈優化->

void popsort1(int* a, size_t n)

} }}

執行結果:

執行結果我們看到了程式減少了迴圈次數,節約了效率,現在程式最好的時間複雜度為o(n). 就是剛剛好陣列有序的時候.最壞的時間

複雜度還是o(n^2)

現在我們思考還可不可以優

化?? 讓它的平均時間複雜度能夠更好一點. 現在我們只能從內部這個

for (j = 0; j < n - i - 1; j++)迴圈入手了.

我們想讓她少迴圈一點,只能從j < n-i-1這裡入手.這裡我還有一種思路,我們首先

明白乙個原理,設每次最後交換的地方為k. 那麼a[k]~a[n]一定是

有序的.如果你好好思考一下,看看這個道理到底對不對. 想不來

沒關係,我還有圖!!! 

那麼優化就很簡單了,只需要改變內層for迴圈判斷條件. 每次記錄最後一次交換資料的位置k,然後for (j = 0; j < k; j++)這樣

改變for迴圈條件即

可.這樣我們的優化就完畢了~  這個時候你的氣泡排序法的效率將會大大提高.你已經很盡力的優化它了. 由於

這個優化效果沒有辦法直觀展示.直接

**實現了:

//內迴圈優化->

void popsort3(int* a, size_t n)

} k = m;

}}

氣泡排序這個演算法大概優化就這麼多吧. 我們平時寫**記著多多想著**可不可以優化.這才是乙個好的程式設計師的標準. 排序

這裡還有很多方法,

比如和冒泡很相似的

插入排序

. 如果不了解可以戳進來.

氣泡排序及其優化

然則 2015年12月30日發布 氣泡排序是比較簡單的,其排序步驟就是比較相鄰元素並將較大的往後移。每掃瞄一輪,將確定乙個元素的位置。實現如下 void sort int a 對氣泡排序的優化主要是減少交換次數。如果一次掃瞄中元素沒有發生交換,那麼排序就可以結束了。為此可設定一標誌量flag,預設為...

氣泡排序及其優化

課程名稱 資料結構 實驗專案名稱 排序演算法的實現與比較 實驗目的 1 掌握優化氣泡排序的演算法 實驗要求 1 對於輸入的任意乙個整型資料序列,將其進行氣泡排序,要求該氣泡排序的演算法為優化之後的演算法,即 a.設定flag變數,當一趟排序結束後flag的值未更新,剛說明序列已經有序,停止排序 b....

氣泡排序及其優化

bubble sort比較簡單,本文首先列出了基礎版本bubble sort的偽 之後做兩點小的優化。1.基礎版本bubblesort 原始版的bubblesort 時間複雜度為o n 2 function bubblesort array x,int length for int i 0 i le...