演算法筆記|泡沫排序法( Bubble Sort )

更新於 發佈於 閱讀時間約 2 分鐘

基本概念


  泡沫排序法的概念很簡單,假設有一串數列,分別將相鄰的兩個元素比大小,如果左側的數字較大則交換,經過一個大迴圈後,最大值會跑到最右邊。

  假設有n筆元素,則需比較n-1次迴圈,在一次迴圈中當有n筆資料則需比較n-1次。如下圖,紅字為比較的對象,藍字為比較後是否對調的結果。


圖解泡沫排序法



第1大圈 第1次比較

raw-image

比較index 0 跟 1 的值,因為8>2則對調

raw-image

第1大圈 第2次比較

raw-image

比較index 1 跟 2 的值,因為8>5則對調

raw-image

第1大圈 第3次比較

raw-image

比較index 2 跟 3 的值,因為8>1則對調

raw-image

第1大圈 第4次比較

raw-image

比較index 3 跟 4 的值,因為8<12則不動

raw-image

第2大圈 第1次比較

raw-image

比較index 0 跟 1 的值,因為2<5則不動

raw-image

第2大圈 第2次比較


raw-image

比較index 1 跟 2 的值,因為5>1則對調

raw-image

第2大圈 第3次比較

raw-image

因為上一輪第一大圈已經確定最右邊為最大值,所以這輪只需要比較3次即可,相信大家已經發現規律了,再來就直接跳到第4大圈第1次比較。

第4大圈 第1次比較

raw-image

透過泡沫排序法,每一大圈的比較,把最大值換到最右邊,最終可以得到由小排到大的數列。


時間複雜度計算


  第1大圈的比較次數是n-1次,第2大圈是n-2次,第n-1圈的時候是1次,

(n-1)+(n-2)+ ....... +1 = (n^2-n)/2因此時間複雜度為O(n)=n^2。


  泡沫排序法的缺點是如果數列本來就是一個由小排到大的數列時,他仍會把全部的迴圈跑一次,非常的沒有效率,所以建議可以加入一個判斷,若第一圈的比較中沒有任何一個值交換則結束,這樣時間複雜度則減為O(n)=n


raw-image


泡沫排序法實作


def bubble_sort(arr):
n = len(arr)
# 外層迴圈控制回合數
for i in range(n):
# 內層迴圈進行比較與交換
for j in range(0, n - i - 1):
if arr[j] > arr[j + 1]: # 如果前一個數大於後一個數,則交換
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr

# 測資
numbers = [64, 34, 25, 12, 22, 11, 90]
sorted_numbers = bubble_sort(numbers)
print("排序後的結果:", sorted_numbers)











avatar-img
3會員
4內容數
人生中有的時候你會感知到,現在就是那個命運的分歧點,如果我不挽起袖子努力的話,我這一輩子大概就這樣了,所以我決定開始這個部落格,記錄我每天的努力,也希望可以分享學習的筆記與心得,大家可以一起交流學習。
留言
avatar-img
留言分享你的想法!

































































資治通艦的沙龍 的其他內容
這篇文章探討演算法的效能分析,著重於時間複雜度和空間複雜度的概念。文章首先說明如何判斷演算法的好壞,接著深入分析時間複雜度的計算方法,並以程式碼範例說明Big-O表示法。此外,文章也簡述空間複雜度的概念及其重要性,並提及常見的資料結構。
這篇文章說明演算法的定義、特徵以及一個有趣的小知識。演算法被定義為解決問題的流程,並以機車故障為例說明。文章也列出演算法的五個特徵:輸入、有限性、明確性、有效性及輸出。最後,文章提及世界上公認的第一個演算法是歐幾裡德演算法。
這篇文章探討演算法的效能分析,著重於時間複雜度和空間複雜度的概念。文章首先說明如何判斷演算法的好壞,接著深入分析時間複雜度的計算方法,並以程式碼範例說明Big-O表示法。此外,文章也簡述空間複雜度的概念及其重要性,並提及常見的資料結構。
這篇文章說明演算法的定義、特徵以及一個有趣的小知識。演算法被定義為解決問題的流程,並以機車故障為例說明。文章也列出演算法的五個特徵:輸入、有限性、明確性、有效性及輸出。最後,文章提及世界上公認的第一個演算法是歐幾裡德演算法。
你可能也想看
Google News 追蹤
Thumbnail
題目敘述 Sort Array by Increasing Frequency Leetcode #1636 給定一個輸入陣列,請依照出現頻率的多寡從低頻到高頻排列陣列元素。 如果有兩個元素的出現頻率相同,依照元素大小從大到小排列。 測試範例 Example 1: Input: nums
Thumbnail
給定兩個輸入陣列,第一個陣列代表每個人的姓名,第二個陣列代表每個人的身高。依照身高從高到矮進行排列,輸出每個人的名字。本文介紹了一個根據身高排列人名的算法,並提供了相關的程式碼和時間複雜度分析。
Thumbnail
本文章討論如何使用動態規劃和回頭查看技巧來計算最長遞增子序列的長度,並提供了相關的測試案例和範例。本文還包括了詳細的演算法和程式碼示例,以及時間和空間複雜度的分析。
Thumbnail
給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素大於等於 k。如果無解,回傳-1。尋找k值的方法包括排序法和二分搜尋法,時間複雜度都為O(n log n),空間複雜度為O(1)。關鍵知識點是當解空間具有遞增或遞減的性質時,可以用二分搜尋法加快搜尋效率。
Thumbnail
輸入給定一個已經從小到大排序好,而且彼此互質的整數陣列, 請問任取兩數分別當作分子、分母,第k小的分數是多少? 輸出請以 [分子,分母] 的形式回傳答案。
Thumbnail
題目已經給了依照起點升序排列好的區間陣列。 接下來新插入一個區間,插入後如果和原本的區間重疊,請把他們合併,要求我們輸出插入後的結果。 這是一個線性掃苗,所需時間為O(n)的演算法。 題目已經幫我們排序好區間順序,我們只要接著依序檢查區間、(假如有重疊的話)合併區間。
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
題目敘述 題目會給兩個陣列nums1和nums2。 題目要求我們從中同步選擇長度為k的子序列,並且最大化子序列的分數, 回傳最高的分數值。 分數的定義: 分數 = (nums1[i0] + nums1[i1] +...+ nums1[ik - 1]) * min(nums2[i0] ,
Thumbnail
題目敘述 Sort Array by Increasing Frequency Leetcode #1636 給定一個輸入陣列,請依照出現頻率的多寡從低頻到高頻排列陣列元素。 如果有兩個元素的出現頻率相同,依照元素大小從大到小排列。 測試範例 Example 1: Input: nums
Thumbnail
給定兩個輸入陣列,第一個陣列代表每個人的姓名,第二個陣列代表每個人的身高。依照身高從高到矮進行排列,輸出每個人的名字。本文介紹了一個根據身高排列人名的算法,並提供了相關的程式碼和時間複雜度分析。
Thumbnail
本文章討論如何使用動態規劃和回頭查看技巧來計算最長遞增子序列的長度,並提供了相關的測試案例和範例。本文還包括了詳細的演算法和程式碼示例,以及時間和空間複雜度的分析。
Thumbnail
給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素大於等於 k。如果無解,回傳-1。尋找k值的方法包括排序法和二分搜尋法,時間複雜度都為O(n log n),空間複雜度為O(1)。關鍵知識點是當解空間具有遞增或遞減的性質時,可以用二分搜尋法加快搜尋效率。
Thumbnail
輸入給定一個已經從小到大排序好,而且彼此互質的整數陣列, 請問任取兩數分別當作分子、分母,第k小的分數是多少? 輸出請以 [分子,分母] 的形式回傳答案。
Thumbnail
題目已經給了依照起點升序排列好的區間陣列。 接下來新插入一個區間,插入後如果和原本的區間重疊,請把他們合併,要求我們輸出插入後的結果。 這是一個線性掃苗,所需時間為O(n)的演算法。 題目已經幫我們排序好區間順序,我們只要接著依序檢查區間、(假如有重疊的話)合併區間。
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
題目敘述 題目會給兩個陣列nums1和nums2。 題目要求我們從中同步選擇長度為k的子序列,並且最大化子序列的分數, 回傳最高的分數值。 分數的定義: 分數 = (nums1[i0] + nums1[i1] +...+ nums1[ik - 1]) * min(nums2[i0] ,