冒泡演算法排序及其優化方案

2021-08-21 23:50:45 字數 4045 閱讀 4049

一、什麼是氣泡排序?

氣泡排序(bubble sort)是一種最為基礎的交換排序,相信學過c語言的,都接觸過這種排序演算法。

這篇文章重點應該放在優化上面。

二、氣泡排序的實現思想:

將陣列裡面相鄰的元素兩兩比較,根據大小來交換元素位置,舉個栗子:

這裡有乙個陣列array[4, 6, 5, 8, 9, 3, 2, 1, 7]

首先4和6比較,4小於6,位置不變,接下來6和5比較,6大於5,所以6和5的位置對調,陣列變成[4, 5, 6, 8, 9, 3, 2,1, 7],由於6和5位置對調,接著是6和8比較,6小於8,所以位置不變,如此類推,第一輪排序後,陣列變成[4,5, 6, 8, 3, 2, 1, 7, 9],第二輪又從第乙個元素4開始比較,但是最終比較的元素不是9而是7,因為第一輪比較,已經是確定將最大的元素放到了最後的位置,所以沒有必要與最後的元素進行比較,這一輪最終結果為[4, 5, 6, 3, 2,1, 7, 8, 9],

如此類推,完成全部排序總共需要array.length x( array.length-1)/2次比較(這個是等差數列計算出來的,有興趣的可以自己算一下)。因為每一輪都要全部比較,所以最原始的氣泡排序叫做穩定排序。

根據這種原始思想,可以得到氣泡排序的原始版

public void sortarray(int array)}}

}

我們把每一輪結果羅列出來時,

第三輪結果:[4, 5,  3,  2,1,6,7, 8, 9]

第四輪結果:[4, 3,  2,1,5,6,7, 8, 9]

第五輪結果:[3, 2,1,4,5,6,7, 8, 9]

第六輪結果:[2,1,3,4,5,6,7, 8, 9]

第七輪結果:[1,2,3,4,5,6,7, 8, 9]

第八輪結果:[1,2,3,4,5,6,7, 8, 9]

從結果可以看出,程式做了些「無用功」,為了避免程式做這些「無用功」,要對基礎版本程式作出一些修改,

優化第一版:

public void sortarray(int array)

}if(issorted)

}}

程式定義了乙個boolean型別的issorted變數,用來判斷往後的迴圈當中,陣列是否已經是有序的,每一輪迴圈都會設定其值為true,當有元素對調位置時,就將issorted的值設定為false,表示該陣列還不是有序陣列。每一輪都要判斷issorted的值,如果判斷當前一輪操作沒有元素有位置調換,那麼可以提前結束所有的迴圈。當然,本次栗子中用到的陣列還是需要進行8輪迴圈,因為,第7輪的時候issorted的值會被設定為false,到了第八輪才是true,讀者可以自行舉例別的陣列檢驗。

還是拿回每一輪執行結果出來:

第三輪結果:[4, 5,  3,  2,1, 6,7, 8, 9]

第四輪結果:[4, 3,  2,1, 5,6,7, 8, 9]

第五輪結果:[3, 2,1, 4,5,6,7, 8, 9]

第六輪結果:[2,1, 3,4,5,6,7, 8, 9]

第七輪結果:[1,2,3,4,5,6,7, 8, 9]

第八輪結果:[1,2,3,4,5,6,7, 8, 9]

這裡講解得詳細一點,以第三輪結果,在第四輪執行操作中,4和5比較,4<5,不調換位置,5和3比較,5>3,位置對調,陣列變成[4, 3,5,2,1,6,7, 8, 9],5和2比較,5<2,位置對調,變成[4, 3, 2,5,1,6,7, 8, 9],5和1比較,5>1,位置對調,變成[4, 3, 2,1,5,6,7, 8, 9]。後面就是5和6比較,6和7比較,7和8比較,8和9比較,但是這四次比較對陣列排序都沒有任何「貢獻」,同理,在第五輪迴圈操作中,沒有「貢獻」的操作會增加一次,這是不希望出現的。

這裡要介紹乙個概念——有序區,有序區指數組有序的區域,這裡指數組末尾的有序元素組成的區域(即下劃線標記的區域),在極端的情況,如[9, 8, 7, 6, 5, 4, 3, 2, 1],按照從小到大順序排序,每一輪排序,有序區只增加一位元素,但更多的情況有序區元素是大於迴圈輪次,當有序區元素等於陣列長度時,可以認為這個陣列已經排序完成,所以下面給出第二次優化,

優化第二版:

public void sortarray(int array)

}border = lastindex;

if(issorted)

}}

這一版新增了兩個int型別變數,乙個是border,表示無序項的邊界,同時也是每一輪迴圈的次數設定值,另乙個是lastindex,用來記錄最後元素需要交換的下標值,進行一輪迴圈後,將這個值賦值給border,作為下一輪迴圈的次數。每一輪迴圈,當有元素需要調換位置時,記錄j的位置,當前輪次迴圈結束,就將lastindex賦值給border,最為新一輪迴圈操作的邊界。

以第五輪結果為栗子,[3, 2,1,4,5,6,7, 8, 9]

,在進行第六輪迴圈操作時,3和2比較,3>2,位置對調,變成[2, 3,1,4,5,6,7, 8, 9]

,此時lastindex = j = 0,3和1比較,3>1,位置對調,變成[2,1,3,4,5,6,7, 8, 9]

,此時lastindex = j = 1,3和4比較,3<4,位置不變,如此類推,本輪迴圈結束時,lastindex = 1,那麼此時border = 1,在第七輪迴圈裡面,只需要進行1次比較就可以結束第七輪迴圈。

排序演算法 冒泡演算法及其優化

所謂冒泡演算法,就是第乙個跟第二個比,第二個跟第三個比。首先從第乙個樹比到最後乙個數,如果第乙個比第二個大,那麼一二互換,如果二三比,二大,二三再互換,如此下去,最大的數就會排到最後面,然後就是再從第乙個數比到倒數第二個,重複上面的動作 現在我們看一下 22 54 16 vi bublle 1.c ...

Python氣泡排序演算法及其優化

氣泡排序 所謂冒泡,就是將元素兩兩之間進行比較,誰大就往後移動,直到將最大的元素排到最後面,接著再迴圈一趟,從頭開始進行兩兩比較,而上一趟已經排好的那個元素就不用進行比較了。圖中排好序的元素標記為黃色柱子 氣泡排序 演示 上python 1 defbubble sort items 2for i i...

氣泡排序及其優化

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