DSA MOOC 起泡排序的原理及常數優化

2022-06-04 07:15:10 字數 1961 閱讀 4482

1. bubblesort(起泡排序),原理來自這樣乙個觀察規律:若序列有序,則任意一對相鄰元素順序。其逆否命題為:若存在相鄰元素逆序,則序列無序。

2. 利用這一原理,bubblesort按照逐步消除逆序對的思路來實現整體有序。

3. 實現:對序列進行若干趟掃瞄,每遇到相鄰逆序對,交換之,直至不再存在逆序對。

4. 演算法的正確性分析:

(1)不變性(問題已求解的部分擴大):每一輪掃瞄交換,都會使當前未就位的元素中最大的那個就位(每次冒出乙個最大的泡)

(2)單調性(問題未求解的規模遞減):每一輪掃瞄交換,都會使有序序列長度增1,無序序列長度減1,問題規模也因而減1

5. 實現為如下**:

1

void swap(int& a,int&b)67

void bubblesort(int a,int

n)16

}17 n--;//

一趟掃瞄交換必然會冒出乙個泡~所以後面已就位的元素可以不在下次的掃瞄範圍內了

18} 19}

20

6. 複雜度分析:

(1)基本語句為第12行的if(a[i]>a[i+1])

(2)初始時,必然會進入第9行的while迴圈,然後進入第11行的for迴圈,基本語句被執行n-1次。

(3)最好情況是輸入完全有序,while迴圈只進入一次,for迴圈執行n-1輪,因此基本語句相應地執行n-1次,t(n) = n-1=ω(n)

(4)最壞情況是輸入完全逆序,while迴圈被執行n次;在第 i 輪while迴圈中,for迴圈執行 i 輪,基本語句也相應地執行 i 次。因此基本語句累加執行n(n-1)/2次,t(n)=n(n-1)/2=o(n2)

vector一章,對bubblesort有兩次常數優化。

函式原型是這樣的:

void bubble(rank lo, rank hi);

void bubblesort(rank lo, rank hi);

rank即向量元素的秩,在此被定義為int型。lo和hi為待排序區間的左、右界樁。

外部通過呼叫 v.bubblesort(lo, hi) 來給向量v的區間[lo,hi)排序,而bubblesort呼叫bubble(lo,hi)實現對每個無序子區間的收縮。

最樸素的bubblesort大概是這樣,最好最壞平均情況都為o(n^2)

1

//最樸素版

2void

bubble(rank lo, rank hi) 7}

8}9void

bubblesort(rank lo, rank hi)

第一次改進後是這樣,這種改進很常見,能使最好情況變為為o(n)。

1

bool

bubble(rank lo, rank hi) 8}

9return sorted;//

返回是否已有序10}

11void

bubblesort(rank lo, rank hi)

第二次改進後是這樣,可以跳躍式地收縮區間,降低了平均情況常數因子

1

rank bubble(rank lo, rank hi)

45 swap(_elem[lo - 1

], _elem[lo]);

6if (_elem[lo - 1]>_elem[lo])

9return last;//

last及以後的元素都已就位,不必再進行掃瞄10}

11void

bubblesort(rank lo, rank hi)

第二次改進可用下圖來描述

改進的起泡排序演算法

一 基本思路 氣泡排序是一種簡單的交換類排序。其基本思路是從頭開始掃瞄待排序的元素,在掃瞄過程中依次對相鄰元素進行比較,將關鍵字值大的元素後移。每經過一趟排序後,關鍵字值最大的元素將移到末尾,此時記下該元素的位置,下一趟排序只需要比較到此位置為止,直到所有元素都已有序排列。一般地,對n個元素進行氣泡...

幾種冒泡 起泡 排序的總結

幾種冒泡 起泡 排序的總結 今天把幾種氣泡排序都實現了一下,大概總結一下,個人筆記,有誤幫我指出,謝謝!我總結的大概有這幾種氣泡排序 1 帶標誌的普通氣泡排序 2 雙向氣泡排序 雞尾酒氣泡排序 3 奇偶氣泡排序 4 區域性氣泡排序 5 快速排序 不穩定 先來看 1 簡單氣泡排序 void simso...

幾種冒泡 起泡 排序的總結

今天把幾種氣泡排序都實現了一下,大概總結一下,個人筆記,有誤幫我指出,謝謝!我總結的大概有這幾種氣泡排序 1 帶標誌的普通氣泡排序 2 雙向氣泡排序 雞尾酒氣泡排序 3 奇偶氣泡排序 4 區域性氣泡排序 5 快速排序 不穩定 先來看 1 簡單氣泡排序 void simsort int a,int n...