氣泡排序演算法及其兩種優化

2021-08-16 18:15:36 字數 3399 閱讀 5573

1、排序方法

將被排序的記錄陣列r[1..n]垂直排列,每個記錄r[i]看作是重量為r[i].key的氣泡。根據輕氣泡不能在重氣泡之下的原則,從下往上掃瞄陣列r:凡掃瞄到違反本原則的輕氣泡,就使其向上"飄浮"。如此反覆進行,直到最後任何兩個氣泡都是輕者在上,重者在下為止。

(1)初始

r[1..n]為無序區。

(2)第一趟掃瞄

從無序區底部向上依次比較相鄰的兩個氣泡的重量,若發現輕者在下、重者在上,則交換二者的位置。即依次比較(r[n],r[n-1]),(r[n-1],r[n-2]),…,(r[2],r[1]);對於每對氣泡(r[j+1],r[j]),若r[j+1].key

第一趟掃瞄完畢時,"最輕"的氣泡就飄浮到該區間的頂部,即關鍵字最小的記錄被放在最高位置r[1]上。

(3)第二趟掃瞄

掃瞄r[2..n]。掃瞄完畢時,"次輕"的氣泡飄浮到r[2]的位置上……

最後,經過n-1 趟掃瞄可得到有序區r[1..n]

注意:第i趟掃瞄時,r[1..i-1]和r[i..n]分別為當前的有序區和無序區。掃瞄仍是從無序區底部向上直至該區頂部。掃瞄完畢時,該區中最輕氣泡飄浮到頂部位置r[i]上,結果是r[1..i]變為新的有序區。

2、氣泡排序過程動畫演示

3、氣泡排序演算法

(1)分析

因為每一趟排序都使有序區增加了乙個氣泡,在經過n-1趟排序之後,有序區中就有n-1個氣泡,所以整個氣泡排序過程至多需要進行n-1趟排序。

具體演算法:

[cpp]view plain

copy

//氣泡排序

void

bubblesort1(

int* arr, 

size_t

size)  

}  }  }  

(2)優化1(優化外層迴圈):

若在某一趟排序中未發現氣泡位置的交換,則說明待排序的無序區中所有氣泡均滿足輕者在上,重者在下的原則,因此,氣泡排序過程可在此趟排序後終止。為此,在下面給出的演算法中,引入乙個標籤flag,在每趟排序開始前,先將其置為0。若排序過程中發生了交換,則將其置為1。各趟排序結束時檢查flag,若未曾發生過交換則終止演算法,不再進行下一趟排序。

具體演算法:

[cpp]view plain

copy

//氣泡排序優化1

void

bubblesort2(

int* arr, 

size_t

size)  

}  //判斷標誌位是否為0,如果為0,說明後面的元素已經有序,就直接return

if(flag == 0)  

}  }  4、演算法分析

(1)演算法的最好時間複雜度

若檔案的初始狀態是正序的,一趟掃瞄即可完成排序。所需的關鍵字比較次數c和記錄移動次數m均達到最小值:

c(min)=n-1

m(min)=0。

氣泡排序最好的時間複雜度為o(n)。

(2)演算法的最壞時間複雜度

若初始檔案是反序的,需要進行n-1趟排序。每趟排序要進行n-i次關鍵字的比較(1≤i≤n-1),且每次比較都必須移動記錄三次來達到交換記錄位置。在這種情況下,比較和移動次數均達到最大值:

c(max)=n(n-1)/2=o(n^2)

m(max)=3n(n-1)/2=o(n^2)

氣泡排序的最壞時間複雜度為o(n^2)。

(3)演算法的平均時間複雜度為o(n^2)

雖然氣泡排序不一定要進行n-1趟,但由於它的記錄移動次數較多,故平均時間效能比直接插入排序要差得多。

(4)演算法穩定性

氣泡排序是就地排序,且它是穩定的。

5、演算法優化2(優化內層迴圈)

(1)記住最後一次交換發生位置lastexchange的氣泡排序

在每趟掃瞄中,記住最後一次交換發生的位置lastexchange,(該位置之後的相鄰記錄均已有序)。下一趟排序開始時,r[1..lastexchange-1]是無序區,r[lastexchange..n]是有序區。這樣,一趟排序可能使當前無序區擴充多個記錄,因此記住最後一次交換發生的位置lastexchange,從而減少排序的趟數。

具體演算法:

[cpp]view plain

copy

//氣泡排序優化2

void

bubblesort3(

int* arr, 

size_t

size)  

}  k = pos;  

//判斷標誌位是否為0,如果為0,說明後面的元素已經有序,就直接return

if(flag == 0)  

}  }  完整**實現:

[cpp]view plain

copy

#include

using

namespace

std;  

#include

//氣泡排序

void

bubblesort1(

int* arr, 

size_t

size)  

}  }  }  

//氣泡排序優化1

void

bubblesort2(

int* arr, 

size_t

size)  

}  //判斷標誌位是否為0,如果為0,說明後面的元素已經有序,就直接return

if(flag == 0)  

}  }  //氣泡排序優化2

void

bubblesort3(

int* arr, 

size_t

size)  

}  k = pos;  

//判斷標誌位是否為0,如果為0,說明後面的元素已經有序,就直接return

if(flag == 0)  

}  }  int

main()  

;  cout <

;  for

(int

i = 0; i 

cout <

/*bubblesort1(arr, 5);*/

/*bubblesort2(arr, 5);*/

bubblesort3(arr, 5);  

cout <

;  for

(int

i = 0; i 

cout <

system("pause"

);  

return

0;  

}  執行結果:

初始順序為:5 4 3 2 1

氣泡排序後順序為:1 2 3 4 5

氣泡排序演算法及其兩種優化

1 排序方法 將被排序的記錄陣列r 1.n 垂直排列,每個記錄r i 看作是重量為r i key的氣泡。根據輕氣泡不能在重氣泡之下的原則,從下往上掃瞄陣列r 凡掃瞄到違反本原則的輕氣泡,就使其向上 飄浮 如此反覆進行,直到最後任何兩個氣泡都是輕者在上,重者在下為止。1 初始 r 1.n 為無序區。2...

氣泡排序演算法的兩種優化

氣泡排序 三種實現,兩種優化 首先,我們先介紹bubblesort 就是氣泡排序,氣泡排序大家應該最熟悉不過了 氣泡排序演算法的運作如下 從後往前 1.比較相鄰的元素。如果第乙個比第二個大,就交換他們兩個。2.對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最...

兩種氣泡排序的比較及冒泡演算法優化

第一種 void bubblesort int array,int len if noswap break 第二種 void bubblesort int array,int len if noswap break 沒有優化 void bubblesort1 int arr,int len 沒有優化...