算法學習筆記:11.冒泡排序——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

在排序算法的大家族中,冒泡排序是最基礎也最經典的算法之一。它的核心思想簡單易懂,通過重復地走訪待排序序列,一次比較兩個相鄰的元素,若它們的順序錯誤就把它們交換過來,直到沒有需要交換的元素為止。雖然冒泡排序的時間復雜度較高,在大規模數據排序中并不常用,但它是理解排序算法思想的絕佳入門案例,也是計算機考研 408 和算法學習中的基礎內容。

冒泡排序的基本概念

冒泡排序(Bubble Sort)之所以被稱為 “冒泡”,是因為在排序過程中,較小的元素會像水中的氣泡一樣逐漸 “上浮” 到序列的頂端,而較大的元素則會 “下沉” 到序列的末端。

例如,對于一個無序序列 [5, 2, 9, 1, 5, 6],使用冒泡排序進行排序時,過程如下:

  • 第一輪比較后,最大的元素 9 會 “下沉” 到序列的最后位置,序列變為 [2, 5, 1, 5, 6, 9]。
  • 第二輪比較后,第二大的元素 6 會 “下沉” 到倒數第二個位置,序列變為 [2, 1, 5, 5, 6, 9]。
  • 繼續重復這個過程,直到整個序列變得有序。

冒泡排序的算法思想

冒泡排序的核心思想是通過相鄰元素的比較和交換,使較大的元素逐漸 “下沉” 到序列的末端。其基本思路遵循以下步驟:

  1. 遍歷序列:從序列的第一個元素開始,依次比較相鄰的兩個元素。
  1. 比較與交換:如果前一個元素大于后一個元素,則交換這兩個元素的位置,確保較大的元素向后移動。
  1. 重復迭代:完成一輪遍歷后,最大的元素會 “下沉” 到序列的最后一個位置。然后忽略已經 “下沉” 到位的元素,對剩余的元素重復上述遍歷、比較和交換過程。
  1. 終止條件:當在一輪遍歷中沒有發生任何元素交換時,說明序列已經有序,排序結束。

冒泡排序的關鍵在于 “逐輪下沉最大元素”,每一輪排序都會確定一個元素的最終位置。對于長度為n的序列,最多需要進行n-1輪排序(在最壞情況下,即序列完全逆序時)。

冒泡排序的解題思路

使用冒泡排序解決實際問題時,通常遵循以下步驟:

  1. 確定待排序序列:明確需要排序的數據集合,可以是數組、列表等數據結構。
  1. 初始化控制變量:設置一個標志變量(如swapped),用于記錄在一輪遍歷中是否發生了元素交換,初始值為false。
  1. 執行多輪排序
    • 每輪遍歷從序列的第一個元素開始,到未排序部分的最后一個元素結束。
    • 在遍歷過程中,比較相鄰元素,若前大后小則交換,并將標志變量設為true。
    • 一輪遍歷結束后,檢查標志變量。若為false,說明序列已有序,退出循環;若為true,則重置標志變量,繼續下一輪排序。
  1. 返回排序結果:排序完成后,返回有序的序列。

通過優化標志變量,可以避免在序列已經有序后繼續不必要的遍歷,提高算法效率。

LeetCode 例題及 Java 代碼實現

例題 1:排序數組(LeetCode 912)

給你一個整數數組 nums,請你將該數組升序排列。

解題思路

本題是典型的排序問題,可直接使用冒泡排序求解。按照上述解題思路,通過多輪遍歷、比較和交換,將數組升序排列。

Java 代碼實現
import java.util.Arrays;public class SortArray {public int[] sortArray(int[] nums) {int n = nums.length;// 外層循環控制排序輪數,最多n-1輪for (int i = 0; i < n - 1; i++) {boolean swapped = false;// 內層循環控制每輪比較的范圍,每輪結束后最大元素已沉底,無需再比較for (int j = 0; j < n - 1 - i; j++) {if (nums[j] > nums[j + 1]) {// 交換相鄰元素int temp = nums[j];nums[j] = nums[j + 1];nums[j + 1] = temp;swapped = true;}}// 若本輪無交換,說明數組已有序,提前退出if (!swapped) {break;}}return nums;}public static void main(String[] args) {SortArray solution = new SortArray();int[] nums = {5, 2, 9, 1, 5, 6};int[] sortedNums = solution.sortArray(nums);System.out.println(Arrays.toString(sortedNums)); // 輸出:[1, 2, 5, 5, 6, 9]}}

例題 2:最大間距(LeetCode 164)

給定一個無序的數組 nums,返回數組在排序之后,相鄰元素之間最大的差值。如果數組元素個數小于 2,則返回 0。

解題思路

本題可先使用冒泡排序對數組進行排序,然后遍歷排序后的數組,計算相鄰元素的差值,記錄最大差值。需要注意的是,由于冒泡排序在處理大規模數據時效率較低,本題僅作為冒泡排序應用的示例,實際解題中更推薦使用基數排序等高效算法。

Java 代碼實現
public class MaximumGap {public int maximumGap(int[] nums) {int n = nums.length;if (n < 2) {return 0;}// 先使用冒泡排序對數組排序bubbleSort(nums);// 計算相鄰元素的最大差值int maxGap = 0;for (int i = 1; i < n; i++) {maxGap = Math.max(maxGap, nums[i] - nums[i - 1]);}return maxGap;}// 冒泡排序實現private void bubbleSort(int[] nums) {int n = nums.length;for (int i = 0; i < n - 1; i++) {boolean swapped = false;for (int j = 0; j < n - 1 - i; j++) {if (nums[j] > nums[j + 1]) {int temp = nums[j];nums[j] = nums[j + 1];nums[j + 1] = temp;swapped = true;}}if (!swapped) {break;}}}public static void main(String[] args) {MaximumGap solution = new MaximumGap();int[] nums = {3, 6, 9, 1};System.out.println(solution.maximumGap(nums)); // 輸出:3(排序后為[1,3,6,9],最大間距為6-3=3)}}

冒泡排序與考研 408

在計算機考研 408 中,冒泡排序是數據結構部分的基礎考點,主要涉及以下幾個方面:

  1. 算法原理與實現:考研 408 常考查冒泡排序的基本原理、執行過程和代碼實現。要求考生能夠手動模擬冒泡排序在給定序列上的每一步操作,包括元素的比較、交換和每輪結束后的序列狀態。例如,給定一個逆序數組,寫出冒泡排序每一輪后的結果。
  1. 時間復雜度與空間復雜度分析
    • 時間復雜度
      • 最壞情況:當序列完全逆序時,每輪都需要進行n-i-1次比較和交換(i為輪次),總比較次數為(n-1)+(n-2)+...+1 = n(n-1)/2,時間復雜度為\(O(n^2)\)。
      • 最好情況:當序列已經有序時,只需進行 1 輪遍歷(n-1次比較),且無交換操作,時間復雜度為\(O(n)\)。
      • 平均情況:時間復雜度為\(O(n^2)\)。
    • 空間復雜度:冒泡排序是原地排序算法,僅需要常數級別的額外空間(用于臨時變量和標志變量),空間復雜度為\(O(1)\)。
  1. 算法特性
    • 穩定性:冒泡排序是穩定的排序算法。在比較相鄰元素時,只有當nums[j] > nums[j+1]時才進行交換,相等元素的相對順序不會改變。
    • 原地性:不需要額外的輔助空間,直接在原序列上進行排序。
    • 適應性:通過標志變量優化后,對于接近有序的序列,效率會顯著提高(最好情況為\(O(n)\))。
  1. 與其他排序算法的對比:考研 408 中常將冒泡排序與插入排序、選擇排序等簡單排序算法進行對比,考查它們在時間復雜度、空間復雜度、穩定性、適用場景等方面的差異。例如:
    • 冒泡排序和插入排序的最好時間復雜度都是\(O(n)\),但插入排序在實際應用中通常比冒泡排序更高效(減少了元素交換的次數)。
    • 選擇排序的時間復雜度始終為\(O(n^2)\),且不穩定,而冒泡排序在最好情況下更優且穩定。
  1. 算法優化:考研中可能會考查冒泡排序的優化方法,除了上述的標志變量優化外,還包括 “記錄最后一次交換的位置”,以此確定下一輪遍歷的終點(因為最后一次交換位置之后的元素已經有序),進一步減少比較次數。

總結

冒泡排序作為最基礎的排序算法之一,雖然在大規模數據排序中效率不高,但其簡單直觀的思想和清晰的執行過程,使其成為理解排序算法的入門首選。通過本文的學習,我們掌握了冒泡排序的算法思想、解題思路、LeetCode 實戰應用以及考研 408 中的考點。

在學習過程中,建議結合手動模擬排序過程加深對算法的理解,同時對比其他簡單排序算法(如插入排序、選擇排序)的異同,形成系統的知識體系。對于考研 408 考生,需重點掌握冒泡排序的時間復雜度分析、穩定性判斷以及與其他算法的對比,確保在考試中能夠準確解答相關問題。

希望本文能夠幫助讀者更深入地理解冒泡排序,并在實際項目中發揮其優勢。謝謝閱讀!


希望這份博客能夠幫助到你。如果有其他需要修改或添加的地方,請隨時告訴我。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/90540.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/90540.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/90540.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux小白學習基礎內容

記錄第一天重新學習2025/7/10 15&#xff1a;467/10 17&#xff1a;02這里面一個命令帶多個參數舉例&#xff08;多個參數之間用空格隔開&#xff09;ls&#xff08;命令&#xff09; ~ / /etc/&#xff08;參數&#xff09; :這里就是同時查看主機的家目錄&#xff0c;根目…

從零開始搭建深度學習大廈系列-2.卷積神經網絡基礎(5-9)

(1)本人挑戰手寫代碼驗證理論&#xff0c;獲得一些AI工具無法提供的收獲和思考&#xff0c;對于一些我無法回答的疑問請大家在評論區指教&#xff1b; (2)本系列文章有很多細節需要弄清楚&#xff0c;但是考慮到讀者的吸收情況和文章篇幅限制&#xff0c;選擇重點進行分享&…

【iOS設計模式】深入理解MVC架構 - 重構你的第一個App

目錄 一、MVC模式概述 二、創建Model層 1. 新建Person模型類 2. 實現Person類 三、重構ViewController 1. 修改ViewController.h 2. 重構ViewController.m 四、MVC組件詳解 1. Model&#xff08;Person類&#xff09; 2. View&#xff08;Storyboard中的UI元素&#x…

前端項目集成lint-staged

lint-staged (lint-staged) 這個插件可以只針對進入git暫存區中的代碼進行代碼格式檢查與修復&#xff0c;極大提升效率&#xff0c;避免掃描整個項目文件&#xff0c;代碼風格控制 eslint prettier stylelint 看這兩篇文章 前端項目vue3項目集成eslint9.x跟prettier 前端項…

李宏毅genai筆記:模型編輯

0 和post training的區別直接用post training的方法是有挑戰的&#xff0c;因為通常訓練資料只有一筆而且之后不管問什么問題&#xff0c;都有可能只是這個答案了1 模型編輯的評估方案 reliability——同樣的問題&#xff0c;需要是目標答案generalization——問題&#xff08;…

Oracle:union all和union區別

UNION ALL和UNION在Oracle中的主要區別體現在處理重復記錄、性能及結果排序上&#xff1a;處理重復記錄?UNION?&#xff1a;自動去除重復記錄&#xff0c;確保最終結果唯一。?UNION ALL?&#xff1a;保留所有記錄&#xff0c;包括完全重復的行。性能表現?UNION?&#xff…

[C#/.NET] 內網開發中如何使用 System.Text.Json 實現 JSON 解析(無需 NuGet)

在實際的企業開發環境中&#xff0c;尤其是內網隔離環境&#xff0c;開發人員經常面臨無法使用 NuGet 安裝外部包的問題。對于基于 .NET Framework 4.8 的應用&#xff0c;JSON 解析是一個常見的需求&#xff0c;但初始項目中往往未包含任何 JSON 處理相關的程序集。這時&#…

JVM(Java 虛擬機)的介紹

JVM原理JVM 核心架構與工作流程1. 類加載機制&#xff08;Class Loading&#xff09;2. 運行時數據區&#xff08;Runtime Data Areas&#xff09;堆&#xff08;Heap&#xff09;方法區&#xff08;Method Area&#xff09;:元空間&#xff08;Metaspace&#xff09;公共區域虛…

Qt 信號槽的擴展知識

Qt 信號槽的擴展知識一、信號與槽的重載Qt信號與槽的重載問題注意事項示例場景二、一個信號連接多個槽1、直接連接多個槽2、使用lambda表達式連接3、連接順序控制4、斷開特定連接5、自動連接方式三、 多個信號連接一個槽基本連接語法使用QSignalMapper區分信號源&#xff08;Qt…

鏈表算法之【合并兩個有序鏈表】

目錄 LeetCode-21題 LeetCode-21題 將兩個升序鏈表合并成一個新的升序鏈表并返回 class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {if (list1 null)return list2;if (list2 null)return list1;ListNode dummyHead new ListNode();ListN…

Linux - firewall 防火墻

&#x1f525; 什么是 firewalld&#xff1f;firewalld 是一個動態管理防火墻的守護進程&#xff08;daemon&#xff09;&#xff0c;它提供了一個 D-Bus 接口來管理系統或用戶的防火墻規則。與傳統的靜態 iptables 不同&#xff0c;firewalld 支持&#xff1a;區域&#xff08…

【GESP】C++二級真題 luogu-B4356 [GESP202506 二級] 數三角形

GESP C二級&#xff0c;2025年6月真題&#xff0c;多重循環&#xff0c;難度★?☆☆☆。 題目題解詳見&#xff1a;【GESP】C二級真題 luogu-B4356 [GESP202506 二級] 數三角形 | OneCoder 【GESP】C二級真題 luogu-B4356 [GESP202506 二級] 數三角形 | OneCoderGESP C二級&…

遙感影像巖性分類:基于CNN與CNN-EL集成學習的深度學習方法

遙感影像巖性分類&#xff1a;基于CNN與CNN-EL集成學習的深度學習方法 大家好&#xff0c;我是微學AI&#xff0c;今天給大家介紹一下遙感影像巖性分類&#xff1a;基于CNN與CNN-EL集成學習的深度學習方法。該方法充分利用了多源遙感數據的光譜和空間信息&#xff0c;同時結合…

【STM32 學習筆記】SPI通信協議

SPI通信協議 SPI協議是由摩托羅拉公司提出的通訊協議(Serial Peripheral Interface)&#xff0c;即串行外圍設備接口&#xff0c; 是一種高速全雙工的通信總線。它被廣泛地使用在ADC、LCD等設備與MCU間&#xff0c;要求通訊速率較高的場合。 ??學習本章時&#xff0c;可與I2C…

Kafka如何做到消息不丟失

一、三種消息傳遞語義(Message Delivery Semantics):核心是“消息被消費處理的次數” Kafka的三種傳遞語義本質上描述的是“一條消息從生產到最終被消費者處理完成,可能出現的次數”,這由生產者的消息寫入可靠性和消費者的offset提交策略共同決定。 1. At most once(最…

HEVC/H.265 碼流分析工具 HEVCESBrowser 使用教程

引言 研究視頻編解碼的都知道&#xff0c;少不了各類的分析工具助力標準研究和算法開發&#xff0c;目前最出名的流媒體分析工具就是elecard系列&#xff0c;但基于一些原因可能大家用的都比較少。因此&#xff0c;找到合適的碼流分析工具才是編解碼研究的便捷途徑&#xff0c…

量子計算+AI芯片:光子計算如何重構神經網絡硬件生態

前言 前些天發現了一個巨牛的人工智能免費學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站 量子計算AI芯片&#xff1a;光子計算如何重構神經網絡硬件生態 ——2025年超異構計算架構下的萬億參數模型訓練革命 產業拐點&a…

linux 4.14 kernel屏蔽arm arch timer的方法

在 ARMv7 架構的單核 CPU 系統中&#xff0c;完全禁用 coretime 時鐘中斷&#xff08;通常是 ARM 私有定時器中斷&#xff09;需要謹慎操作&#xff0c;因為這會導致調度器無法工作&#xff0c;系統可能失去響應。以下是實現方法及注意事項&#xff1a;方法 1&#xff1a;通過 …

[實戰]調頻(FM)和調幅(AM)信號生成(完整C語言實現)

調頻&#xff08;FM&#xff09;和調幅&#xff08;AM&#xff09;信號生成 文章目錄調頻&#xff08;FM&#xff09;和調幅&#xff08;AM&#xff09;信號生成1. 調頻&#xff08;FM&#xff09;和調幅&#xff08;AM&#xff09;信號原理與信號生成調幅&#xff08;AM&#…

【LeetCode 熱題 100】21. 合并兩個有序鏈表——(解法一)迭代法

Problem: 21. 合并兩個有序鏈表 題目&#xff1a;將兩個升序鏈表合并為一個新的 升序 鏈表并返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。 文章目錄整體思路完整代碼時空復雜度時間復雜度&#xff1a;O(M N)空間復雜度&#xff1a;O(1)整體思路 這段代碼旨在解決…