
- 資料結構與演算法
- DSA - 首頁
- DSA - 概述
- DSA - 環境設定
- DSA - 演算法基礎
- DSA - 漸進分析
- 資料結構
- DSA - 資料結構基礎
- DSA - 資料結構和型別
- DSA - 陣列資料結構
- 連結串列
- DSA - 連結串列資料結構
- DSA - 雙向連結串列資料結構
- DSA - 迴圈連結串列資料結構
- 棧與佇列
- DSA - 棧資料結構
- DSA - 表示式解析
- DSA - 佇列資料結構
- 搜尋演算法
- DSA - 搜尋演算法
- DSA - 線性搜尋演算法
- DSA - 二分搜尋演算法
- DSA - 插值搜尋
- DSA - 跳躍搜尋演算法
- DSA - 指數搜尋
- DSA - 斐波那契搜尋
- DSA - 子列表搜尋
- DSA - 雜湊表
- 排序演算法
- DSA - 排序演算法
- DSA - 氣泡排序演算法
- DSA - 插入排序演算法
- DSA - 選擇排序演算法
- DSA - 歸併排序演算法
- DSA - 希爾排序演算法
- DSA - 堆排序
- DSA - 桶排序演算法
- DSA - 計數排序演算法
- DSA - 基數排序演算法
- DSA - 快速排序演算法
- 圖資料結構
- DSA - 圖資料結構
- DSA - 深度優先遍歷
- DSA - 廣度優先遍歷
- DSA - 生成樹
- 樹資料結構
- DSA - 樹資料結構
- DSA - 樹的遍歷
- DSA - 二叉搜尋樹
- DSA - AVL樹
- DSA - 紅黑樹
- DSA - B樹
- DSA - B+樹
- DSA - 伸展樹
- DSA - 字典樹
- DSA - 堆資料結構
- 遞迴
- DSA - 遞迴演算法
- DSA - 使用遞迴的漢諾塔
- DSA - 使用遞迴的斐波那契數列
- 分治法
- DSA - 分治法
- DSA - 最大-最小問題
- DSA - Strassen矩陣乘法
- DSA - Karatsuba演算法
- 貪心演算法
- DSA - 貪心演算法
- DSA - 旅行商問題(貪心法)
- DSA - Prim最小生成樹
- DSA - Kruskal最小生成樹
- DSA - Dijkstra最短路徑演算法
- DSA - 地圖著色演算法
- DSA - 分數揹包問題
- DSA - 帶截止日期的作業排序
- DSA - 最優合併模式演算法
- 動態規劃
- DSA - 動態規劃
- DSA - 矩陣鏈乘法
- DSA - Floyd-Warshall演算法
- DSA - 0-1揹包問題
- DSA - 最長公共子序列演算法
- DSA - 旅行商問題(動態規劃法)
- 近似演算法
- DSA - 近似演算法
- DSA - 頂點覆蓋演算法
- DSA - 集合覆蓋問題
- DSA - 旅行商問題(近似演算法)
- 隨機演算法
- DSA - 隨機演算法
- DSA - 隨機快速排序演算法
- DSA - Karger最小割演算法
- DSA - Fisher-Yates洗牌演算法
- DSA有用資源
- DSA - 問答
- DSA - 快速指南
- DSA - 有用資源
- DSA - 討論
氣泡排序演算法
氣泡排序是一種簡單的排序演算法。這是一種基於比較的排序演算法,其中每對相鄰元素進行比較,如果它們沒有按順序排列,則交換元素。該演算法不適用於大型資料集,因為它的平均和最壞情況複雜度為 O(n2),其中n是專案數。
氣泡排序演算法
氣泡排序是一種基本的排序演算法,它透過重複交換相鄰元素(如有必要)來工作。當不需要交換時,檔案就已排序。
我們假設list是一個包含n個元素的陣列。我們進一步假設swap函式交換給定陣列元素的值。
步驟 1 − 檢查輸入陣列中的第一個元素是否大於陣列中的下一個元素。
步驟 2 − 如果它更大,則交換這兩個元素;否則將指標向前移動到陣列中。
步驟 3 − 重複步驟 2,直到到達陣列的末尾。
步驟 4 − 檢查元素是否已排序;如果沒有,則從陣列的最後一個元素到第一個元素重複相同的過程(步驟 1 到步驟 3)。
步驟 5 − 達到的最終輸出是已排序的陣列。
Algorithm: Sequential-Bubble-Sort (A) fori ← 1 to length [A] do for j ← length [A] down-to i +1 do if A[A] < A[j-1] then Exchange A[j] ⟷ A[j-1]
虛擬碼
我們在演算法中觀察到,氣泡排序會比較每對陣列元素,除非整個陣列完全按升序排序。這可能會導致一些複雜性問題,例如,如果陣列不需要更多交換,因為所有元素都已經是升序的。
為了解決這個問題,我們使用一個標誌變數swapped,它將幫助我們檢視是否發生了任何交換。如果沒有發生交換,即陣列不需要更多處理即可排序,它將退出迴圈。
氣泡排序演算法的虛擬碼可以寫成如下:
voidbubbleSort(int numbers[], intarray_size){ inti, j, temp; for (i = (array_size - 1); i>= 0; i--) for (j = 1; j <= i; j++) if (numbers[j-1] > numbers[j]){ temp = numbers[j-1]; numbers[j-1] = numbers[j]; numbers[j] = temp; } }
分析
這裡,比較次數為
1 + 2 + 3 + ... + (n - 1) = n(n - 1)/2 = O(n2)
顯然,該圖顯示了氣泡排序的n2特性。
在此演算法中,比較次數與資料集無關,即提供的輸入元素是按排序順序、反向順序還是隨機順序。
記憶體需求
從上面描述的演算法可以看出,氣泡排序不需要額外的記憶體。
示例
我們以一個未排序的陣列為例。氣泡排序需要Ο(n2)時間,所以我們將其保持簡短和精確。

氣泡排序從最前面的兩個元素開始,比較它們以檢查哪個更大。

在這種情況下,值 33 大於 14,因此它已經位於排序位置。接下來,我們將 33 與 27 進行比較。

我們發現 27 小於 33,這兩個值必須交換。

接下來我們比較 33 和 35。我們發現兩者都已位於排序位置。

然後我們移動到接下來的兩個值,35 和 10。

然後我們知道 10 小於 35。因此它們沒有排序。我們交換這些值。我們發現我們已經到達陣列的末尾。經過一次迭代後,陣列應該如下所示:

準確地說,我們現在展示了陣列在每次迭代後應該是什麼樣子。在第二次迭代之後,它應該如下所示:


請注意,在每次迭代之後,至少有一個值移動到末尾。




當不需要交換時,氣泡排序知道陣列已完全排序。

現在我們應該研究氣泡排序的一些實際方面。
實現
我們在原始演算法及其改進的虛擬碼中沒有解決的另一個問題是,在每次迭代之後,最高值都會沉澱在陣列的末尾。因此,下一次迭代不需要包含已排序的元素。為此,在我們的實現中,我們限制內迴圈以避免已排序的值。
#include <stdio.h> void bubbleSort(int array[], int size){ for(int i = 0; i<size; i++) { int swaps = 0; //flag to detect any swap is there or not for(int j = 0; j<size-i-1; j++) { if(array[j] > array[j+1]) { //when the current item is bigger than next int temp; temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; swaps = 1; //set swap flag } } if(!swaps) break; // No swap in this pass, so array is sorted } } int main(){ int n; n = 5; int arr[5] = {67, 44, 82, 17, 20}; //initialize an array printf("Array before Sorting: "); for(int i = 0; i<n; i++) printf("%d ",arr[i]); printf("\n"); bubbleSort(arr, n); printf("Array after Sorting: "); for(int i = 0; i<n; i++) printf("%d ", arr[i]); printf("\n"); }
輸出
Array before Sorting: 67 44 82 17 20 Array after Sorting: 17 20 44 67 82
#include<iostream> using namespace std; void bubbleSort(int *array, int size){ for(int i = 0; i<size; i++) { int swaps = 0; //flag to detect any swap is there or not for(int j = 0; j<size-i-1; j++) { if(array[j] > array[j+1]) { //when the current item is bigger than next int temp; temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; swaps = 1; //set swap flag } } if(!swaps) break; // No swap in this pass, so array is sorted } } int main(){ int n; n = 5; int arr[5] = {67, 44, 82, 17, 20}; //initialize an array cout << "Array before Sorting: "; for(int i = 0; i<n; i++) cout << arr[i] << " "; cout << endl; bubbleSort(arr, n); cout << "Array after Sorting: "; for(int i = 0; i<n; i++) cout << arr[i] << " "; cout << endl; }
輸出
Array before Sorting: 67 44 82 17 20 Array after Sorting: 17 20 44 67 82
import java.io.*; import java.util.*; public class BubbleSort { public static void main(String args[]) { int n = 5; int[] arr = {67, 44, 82, 17, 20}; //initialize an array System.out.print("Array before Sorting: "); for(int i = 0; i<n; i++) System.out.print(arr[i] + " "); System.out.println(); for(int i = 0; i<n; i++) { int swaps = 0; //flag to detect any swap is there or not for(int j = 0; j<n-i-1; j++) { if(arr[j] > arr[j+1]) { //when the current item is bigger than next int temp; temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; swaps = 1; //set swap flag } } if(swaps == 0) break; } System.out.print("Array After Sorting: "); for(int i = 0; i<n; i++) System.out.print(arr[i] + " "); System.out.println(); } }
輸出
Array before Sorting: 67 44 82 17 20 Array After Sorting: 17 20 44 67 82
def bubble_sort(array, size): for i in range(size): swaps = 0; for j in range(0, size-i-1): if(arr[j] > arr[j+1]): temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; swaps = 1; if(swaps == 0): break; arr = [67, 44, 82, 17, 20] n = len(arr) print("Array before Sorting: ") print(arr) bubble_sort(arr, n); print("Array after Sorting: ") print(arr)
輸出
Array before Sorting: [67, 44, 82, 17, 20] Array after Sorting: [17, 20, 44, 67, 82]