【資料結構與演算法】內部排序之二:氣泡排序和選擇排序(改進優化,附完整原始碼)
轉載請註明出處:http://blog.csdn.net/ns_code/article/details/20065107
前言
之所以把氣泡排序和選擇排序放在一起,是因為二者的實現程式碼很相似,而且都是最基本的排序方式,非常容易理解和實現。當然,如果僅僅是為了講述這兩種排序方式,那也根本沒必要寫這篇博文了。和上篇博文一樣,我會在氣泡排序和選擇排序原始程式碼的基礎上給出一些改進和優化,這才是本文的重點所在。
原始氣泡排序
氣泡排序的思想很簡單,如果要求排序後序列中元素按照從小到大的順序排列,則氣泡排序的步驟如下:
1、依次比較序列中相鄰的兩個元素,將較大的放在後面,這樣一趟比較後,最大的元素就放在了最後的一個位置;
2、再依次比較相鄰的兩個元素,將第二大的元素最終放到倒數第二個位置;
3、依次迴圈,直到最小的元素放在了第一個位置,排序完成。
根據以上思想,很容易寫出程式碼:
/*
氣泡排序後的順序為從小到大
*/
void Bubble_Sort(int *arr,int len)
{
int i,j,exchange;
for(i=0;i<len-1;i++)
for(j=0;j<len-i-1;j++)
if(arr[j] > arr[j+1])
{
exchange = arr[j];
arr[j] = arr[j+1];
arr[j+1] = exchange;
}
}
改進氣泡排序
我們回過頭來再來看上面氣泡排序的思想,無論原始序列的排序是怎樣的(哪怕已經是從小到大排好的),它都要進行n-1趟比較,每趟比較又要進行n-i-1次相鄰元素間的比較(i為從0開始計的第i趟比較),而實際上,很有可能還沒有進行第n-1趟比較,已經完成了排序,這時候後面的幾趟比較就顯得多餘了,基於此,我們可以做如下改進:設定一個標誌位,如果某一趟有元素髮生交換,則為true,繼續下一趟比較,否則,說明排序已經完成,則標誌位為false,退出迴圈。程式碼實現如下:
/*
氣泡排序後的順序為從小到大
*/
void Bubble_Sort(int *arr,int len)
{
int i,j,exchange;
bool flag = true; //增設標誌位,判斷是否已經完成排序
for(i=0; i<len-1 && flag; i++)
{
flag = false;
for(j=0;j<len-i-1;j++)
if(arr[j] > arr[j+1])
{ //如果本趟比較沒有資料發生交換,說明排序已經完成
//則flag一直為false,從而退出迴圈,不再進行下一趟的比較
exchange = arr[j];
arr[j] = arr[j+1];
arr[j+1] = exchange;
flag = true;
}
}
}
直接選擇排序
直接選擇排序的思想也很簡單,以排序從小到大為例,如下:
1、從第一個元素開始,選出一個最小的元素與第一個元素互換;
2、繼續從第二個元素開始,向後選出最小的元素,與第二個元素互換;
3、依次迴圈執行,直到最大的元素放在了最後一個位置上,排序完成。
我們可以將第一個元素分別與後面的元素進行比較,遇到更小的,就交換,這樣一趟比較下來,第一個元素儲存就是最小值,而後再從第二個元素開似乎,依次與後面的元素比較,遇到更小的,就交換,這樣,第二趟比較下來,第二個元素儲存的就是第二小的值。。。依次迴圈執行,直到完成排序。按照這樣的思路,實現程式碼如下:
/*
第一種形式的選擇排序
選擇排序後的順序為從小到大
*/
void Select_Sort1(int *arr,int len)
{
int i,j;
for(i=0;i<len;i++)
for(j=i+1;j<len;j++)
if(arr[i] > arr[j])
{
int exchange = arr[i];
arr[i] = arr[j];
arr[j] = exchange;
}
}
改進選擇排序
但是我們上篇文章中提到過,在排序中應該儘量避免較多的和元素互換操作,而這裡每比較一次,如果遇到更小的,就要互換一次元素。為了減少元素互換操作,我們可以在每次比較後不直接進行交換,將較小的元素的位置序號記錄下來,這樣一趟比較之後,就會得到最小元素的位置,如果最小值的位置發生了改變,再將該位置的元素與第一個元素互換,依次類推。。。這樣每一趟比較完成後最多隻需執行一次元素互換的操作。實現程式碼如下:
/*
第二種形式的選擇排序,減少了元素互換的操作
選擇排序後的順序為從小到大
*/
void Select_Sort2(int *arr,int len)
{
int i,j,min;
for(i=0;i<len;i++)
{
min = i; //用來記錄每一趟比較的最小值的位置
for(j=i+1;j<len;j++)
if(arr[min] > arr[j])
min = j; //僅記錄最小值的位置
//如果最小值的位置發生了變化,
//則最後執行一次元素互換的操作
if(min != i)
{
int exchange = arr[i];
arr[i] = arr[min];
arr[min] = exchange;
}
}
}
總結
完整原始碼
相關文章
- 排序演算法 - 氣泡排序和選擇排序排序演算法
- 氣泡排序與選擇排序排序
- 選擇排序和氣泡排序排序
- 氣泡排序和選擇排序排序
- 重學資料結構和演算法(四)之氣泡排序、插入排序、選擇排序資料結構演算法排序
- 【資料結構與演算法】內部排序之五:計數排序、基數排序和桶排序(含完整原始碼)資料結構演算法排序原始碼
- 【資料結構與演算法】內部排序之三:堆排序(含完整原始碼)資料結構演算法排序原始碼
- 【資料結構與演算法】內部排序之一:插入排序和希爾排序的N中實現(不斷優化,附完整原始碼)資料結構演算法排序優化原始碼
- 資料結構與演算法——排序演算法-氣泡排序資料結構演算法排序
- #排序演算法#【1】概述、氣泡排序、選擇排序排序演算法
- 氣泡排序和選擇排序詳解排序
- 氣泡排序和選擇排序流程圖排序流程圖
- 排序演算法(氣泡排序,選擇排序,插入排序,希爾排序)排序演算法
- 【資料結構與演算法】內部排序總結(附各種排序演算法原始碼)資料結構演算法排序原始碼
- 資料結構&演算法實踐—氣泡排序及改進資料結構演算法排序
- (一)氣泡排序、選擇排序、插入排序排序
- 八大排序演算法(1)_氣泡排序和選擇排序排序演算法
- 圖形化排序演算法比較:快速排序、插入排序、選擇排序、氣泡排序排序演算法
- 【資料結構】氣泡排序資料結構排序
- 演算法(三)初等排序後篇[選擇和氣泡排序]演算法排序
- 演算法--陣列氣泡排序和選擇排序原理分析演算法陣列排序
- 複習資料結構:排序演算法(二)——氣泡排序資料結構排序演算法
- 9. 氣泡排序,以及如何優化氣泡排序,氣泡排序屬於插入排序排序優化
- JAVA小練習氣泡排序,選擇排序和插入排序Java排序
- 【JS面試向】選擇排序、桶排序、氣泡排序和快速排序簡介JS面試排序
- C++排序演算法之氣泡排序改進版C++排序演算法
- 資料結構與演算法——排序演算法-選擇排序資料結構演算法排序
- 氣泡排序與選擇排序超詳細講解排序
- php實現 氣泡排序,插入排序,選擇排序PHP排序
- 資料結構java版之氣泡排序及優化資料結構Java排序優化
- PHP 常見4種排序 氣泡排序、選擇排序、插入排序、快速排序PHP排序
- 排序演算法–氣泡排序排序演算法
- 排序演算法__氣泡排序排序演算法
- 排序演算法--氣泡排序排序演算法
- 排序演算法-氣泡排序排序演算法
- 排序演算法——氣泡排序排序演算法
- python演算法與資料結構-氣泡排序(32)Python演算法資料結構排序
- 資料結構系列:圖文詳解氣泡排序 & 優化資料結構排序優化