排序---冒泡排序(Bubble Sort)

一、算法核心概念

冒泡排序是一種簡單的交換排序算法,其核心思想是:通過重復遍歷待排序數組,每次比較相鄰的兩個元素,若它們的順序錯誤(如升序排序中前一個元素大于后一個),則交換它們的位置。經過多輪遍歷后,較大的元素會像“氣泡”一樣逐漸“上浮”到數組的末尾,最終使整個數組有序。

二、基本工作原理

升序排序為例,冒泡排序的工作流程可概括為:

  1. 初始狀態:整個數組為“未排序區間”(需排序的元素范圍);
  2. 每輪遍歷:從數組頭部開始,依次比較相鄰元素(arr[j]arr[j+1]),若arr[j] > arr[j+1],則交換兩者位置;
  3. 范圍收縮:每輪遍歷結束后,當前未排序區間中最大的元素會“浮”到區間的末尾,因此下一輪的未排序區間可縮小1個元素(無需再檢查已“浮”到末尾的元素);
  4. 終止條件:當某輪遍歷中沒有發生任何元素交換時,說明數組已完全有序,排序結束。
三、步驟演示(實例解析)

以數組[5, 3, 8, 4, 2]為例,演示升序冒泡排序的過程:

輪次未排序區間遍歷中的比較與交換本輪結束后數組是否發生交換
1[0,4](全數組)比較5&3→交換→[3,5,8,4,2];
比較5&8→不交換;
比較8&4→交換→[3,5,4,8,2];
比較8&2→交換→[3,5,4,2,8]
[3,5,4,2,8]
2[0,3](前4個元素)比較3&5→不交換;
比較5&4→交換→[3,4,5,2,8];
比較5&2→交換→[3,4,2,5,8]
[3,4,2,5,8]
3[0,2](前3個元素)比較3&4→不交換;
比較4&2→交換→[3,2,4,5,8]
[3,2,4,5,8]
4[0,1](前2個元素)比較3&2→交換→[2,3,4,5,8][2,3,4,5,8]
5[0,0](僅第1個元素)無相鄰元素可比較[2,3,4,5,8]否(排序結束)
四、時間復雜度與空間復雜度
  • 時間復雜度

    • 最壞情況:數組完全逆序,需執行n-1輪遍歷,每輪比較n-i次(i為輪次),總操作次數為n+(n-1)+...+1 = n(n-1)/2,故為O(n2)
    • 最好情況:數組已完全有序,若添加“交換標志”優化,僅需1輪遍歷(n-1次比較)即可判斷有序,故為O(n)
    • 平均情況:O(n2)(適用于隨機無序數組)。
  • 空間復雜度
    僅需常數個臨時變量(用于交換元素和記錄標志),故為O(1)(原地排序)。

五、穩定性分析

冒泡排序是穩定的排序算法

  • 穩定性定義:若數組中存在相等元素,排序后它們的相對順序與原數組一致,則算法穩定。
  • 原因:冒泡排序僅在相鄰元素嚴格逆序(如arr[j] > arr[j+1])時才交換,若arr[j] == arr[j+1],不會觸發交換,因此相等元素的相對順序保持不變。
六、優化策略

基礎版冒泡排序在數組已部分有序時仍會執行不必要的遍歷,可通過以下優化提升效率:

1. 交換標志優化(核心優化)

添加一個布爾變量(如swapped),記錄每輪是否發生交換。若某輪未發生交換,說明數組已有序,可直接終止排序。

2. 記錄最后交換位置(進階優化)

每輪遍歷中,記錄最后一次發生交換的位置lastSwapIndex。下一輪遍歷的終點可設為lastSwapIndex(因為該位置之后的元素已有序),減少無效比較。

七、C++實現代碼
1. 基礎版實現
#include <iostream>
#include <vector>
using namespace std;// 基礎版冒泡排序(升序)
void bubbleSortBasic(vector<int>& arr) {int n = arr.size();// 外層循環:控制輪次(最多n-1輪)for (int i = 0; i < n - 1; ++i) {// 內層循環:遍歷未排序區間[0, n-1-i]for (int j = 0; j < n - 1 - i; ++j) {if (arr[j] > arr[j + 1]) {swap(arr[j], arr[j + 1]); // 交換逆序元素}}}
}int main() {vector<int> arr = {5, 3, 8, 4, 2};bubbleSortBasic(arr);for (int num : arr) {cout << num << " "; // 輸出:2 3 4 5 8}return 0;
}
2. 優化版實現(交換標志+最后交換位置)
#include <iostream>
#include <vector>
using namespace std;// 優化版冒泡排序(升序)
void bubbleSortOptimized(vector<int>& arr) {int n = arr.size();int lastSwapIndex = 0; // 記錄最后一次交換的位置int border = n - 1;    // 當前未排序區間的右邊界(初始為數組末尾)for (int i = 0; i < n - 1; ++i) {bool swapped = false; // 標志位:本輪是否發生交換// 內層循環僅遍歷到border(減少無效比較)for (int j = 0; j < border; ++j) {if (arr[j] > arr[j + 1]) {swap(arr[j], arr[j + 1]);swapped = true;lastSwapIndex = j; // 更新最后交換位置}}border = lastSwapIndex; // 收縮未排序區間右邊界if (!swapped) break;    // 未交換,數組已有序,提前終止}
}int main() {vector<int> arr = {5, 3, 8, 4, 2};bubbleSortOptimized(arr);for (int num : arr) {cout << num << " "; // 輸出:2 3 4 5 8}return 0;
}
八、適用場景與局限性
適用場景:
  1. 小規模數據排序:數據量較小時(如n < 100),冒泡排序實現簡單,性能可接受;
  2. 幾乎有序的數據:若數組已接近有序(僅少數元素逆序),優化后的冒泡排序可快速完成排序(接近O(n)復雜度);
  3. 教學場景:算法邏輯直觀,易于理解,適合作為入門排序算法講解。
局限性:
  1. 大規模數據效率低:時間復雜度為O(n2),對于n > 1000的數組,排序速度遠低于O(nlogn)級算法(如快速排序、歸并排序);
  2. 交換操作頻繁:每輪可能發生多次相鄰元素交換,實際運行時間比同復雜度的選擇排序更長(選擇排序每輪僅1次交換)。

冒泡排序是一種直觀、簡單的排序算法,核心通過“相鄰元素比較交換”使大元素逐步上浮。盡管其時間復雜度較高(O(n2)),但在小規模或近乎有序的數據場景中仍有應用價值。通過“交換標志”和“收縮邊界”優化,可顯著提升其在部分有序數據上的性能。

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

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

相關文章

MCP(模型上下文協議)入門教程

MCP&#xff08;模型上下文協議&#xff09;入門教程&#xff1a;連接AI與外部世界的萬能插座 1 MCP是什么&#xff1f; 1.1 基本概念 MCP&#xff08;Model Context Protocol&#xff0c;模型上下文協議&#xff09;是一個開放協議&#xff0c;專門用于AI模型與外部數據源和…

GO開發遇到的報錯問題合集

本文將記錄平時在go開發中遇到的一些錯誤信息&#xff0c;踩過的坑&#xff0c;并分析原因及提供解決方法&#xff0c;持續更新中...1、grpc 接口請求報錯&#xff1a;Error: 13 INTERNAL: Response message parsing error: invalid wire type 7 at offset 316原因&#xff1a;…

Node.js 做 Web 后端優勢為什么這么大?

Node.js自誕生以來&#xff0c;一步步演變變為現代Web后端開發的基石之一。無論是初創公司快速構建原型&#xff0c;還是大型企業支撐高并發業務&#xff0c;好像它哪兒哪兒都在&#xff0c;甚至還有人覺得它威脅到了PHP的地位。 那為什么Node.js 做 Web 后端優勢那么大&#x…

JAVA:IO流之字節輸入流InputStream基礎

我們知道&#xff0c;文件是寫在磁盤中的&#xff0c;而程序的運行又要借助于內存。那么怎么實現內存和磁盤的“互動”呢&#xff1f;這就要借助“流”來實現了。內存具體指的就是我們的java程序&#xff0c;而磁盤具體指的是我們的文件。從磁盤到內存叫輸入&#xff0c;從內存…

23種設計模式——橋接模式 (Bridge Pattern)詳解

?作者簡介&#xff1a;大家好&#xff0c;我是 Meteors., 向往著更加簡潔高效的代碼寫法與編程方式&#xff0c;持續分享Java技術內容。 &#x1f34e;個人主頁&#xff1a;Meteors.的博客 &#x1f49e;當前專欄&#xff1a;設計模式 ?特色專欄&#xff1a;知識分享 &#x…

Python爬蟲實戰:研究Axes Grid模塊,構建旅游平臺酒店數據采集和分析系統

1. 引言 1.1 研究背景 隨著互聯網技術的飛速發展,全球數據總量呈現指數級增長。據國際數據公司(IDC)預測,到 2025 年全球數據圈將達到 175ZB,其中非結構化數據占比超過 80%。這些數據廣泛分布于各類網站平臺,包含著用戶行為、市場趨勢、產品特征等豐富信息。如何高效獲…

光照邊疆平臺|面向邊疆地區的現代化內容與信息服務系統

光照邊疆平臺&#xff5c;面向邊疆地區的現代化內容與信息服務系統聚焦“邊疆資訊 邊疆風光 用戶互動 后臺可視化管控”的高顏值內容平臺&#xff0c;適合展示、傳播與運營邊疆主題內容。系統定位與價值 主題聚焦&#xff1a;以“邊疆”為核心&#xff0c;統一內容語義與視覺…

刪除元素(不是刪除而是覆蓋)快慢指針 慢指針是覆蓋位置,快指針找元素

&#x1f4dd; 題目&#xff1a;移除元素題目描述&#xff1a; 給定數組和值val&#xff0c;原地移除所有等于val的元素&#xff0c;返回新長度。例子&#xff1a; nums [3,2,2,3], val 3 → nums [2,2,_,_], return 2&#x1f525; 暴力法思路&#xff1a;暴力法想法&#…

10 【C++】泛型編程

文章目錄前言泛型編程&#xff08;模板&#xff09;1. 函數模板1.1 函數模板格式1.2 函數模板的實例化隱式實例化顯式指定模板參數實例化1.3 函數模板實例化的原理1.4 模板參數的匹配原則2. 類模板2.1 類模板的格式2.2 類模板的實例化2.3 類模板實例化的原理2.4 類模板的匹配原…

【基于YOLO和Web的交通工具識別系統】

系統功能 視頻檢測&#xff1a;對輸入的視頻流進行實時或離線分析&#xff0c;自動識別視頻中出現的交通工具&#xff08;如飛機、自行車等&#xff09;及行人&#xff0c;輸出包含目標類別、位置等信息的檢測結果。攝像檢測&#xff1a;通過連接攝像頭設備&#xff0c;對實時…

Python進程,線程

目錄 一、多任務 1.1定義 1.2具體體現 1.3并發和并行 1.3.1并發操作 1.3.2并行操作 1.3.3對比 二、進程 2.1概念 2.2特點 2.3進程狀態 2.4多進程 2.5多進程實現 2.6進程鎖 三、線程 3.1概念 3.2特點 3.3適用場景 3.4多線程實現 四、對比 4.1關系對? 4.2區…

【Element Plus 表單組件樣式統一 CSS 文字特效實現指南】

Element Plus 表單組件樣式統一 & CSS 文字特效實現指南 前言 在使用 Element Plus 組件庫開發表單頁面時&#xff0c;我們遇到了一個看似簡單卻很有趣的問題&#xff1a;el-input、el-select 和 el-textarea 在禁用狀態下的文字顏色不一致。通過深入研究&#xff0c;我們…

網絡通信與協議棧 -- OSI,TCP/IP模型,協議族,UDP編程

網絡通信的核心是實現不同主機上進程間的數據交換&#xff0c;其技術體系圍繞 “協議分層模型” 展開&#xff0c;向下依賴硬件介質傳輸電 / 光信號&#xff0c;向上支撐各類網絡應用&#xff08;如網頁瀏覽、文件傳輸&#xff09;。本文結合 OSI 理論框架與 TCP/IP 工業標準&a…

HarmonyOS 新一代聲明式 UI 彈窗機制:從 AlertDialog 到 CustomDialogController 的深度解析與實踐

好的&#xff0c;請看這篇關于 HarmonyOS 新一代聲明式 UI 彈窗機制的技術文章。 HarmonyOS 新一代聲明式 UI 彈窗機制&#xff1a;從 AlertDialog 到 CustomDialogController 的深度解析與實踐 引言 在 HarmonyOS 應用開發中&#xff0c;彈窗&#xff08;Dialog&#xff09;是…

混合推理模型(快思考、慢思考模型)

目錄基礎transformer架構、transformers庫預訓練模型的微調&#xff08;Fine-tuning&#xff09;預訓練微調的大模型應用模式base 模型、instruct 模型區別Hugging Face 上如何查看base模型、instruct模型混合推理模型大模型里的快思考 vs 慢思考qwen3模型含特殊 ChatML / 模型…

prometheus+grafana搭建

部署 prometheus 安裝 # 1,下載 wget https://github.com/prometheus/prometheus/releases/download/v2.45.1/prometheus-3.5.0.linux-amd64.tar.gz# 2,部署 tar -zxvf prometheus-3.5.0.linux-amd64.tar.gz -C /opt/ cd /opt/ mv ./prometheus-3.5.0.linux-amd64 …

MR30分布式I/O在面機裝備中的應用

隨著食品加工行業向自動化、智能化轉型&#xff0c;面機裝備對控制系統的響應速度、布線靈活性及穩定性提出了更高要求。本案例以某大型食品機械制造企業的全自動面條生產線升級項目為背景&#xff0c;引入 MR30 分布式 IO 模塊替代傳統集中式 IO 方案。通過將 MR30 分布式 IO …

Matlab使用小技巧合集(系列四):Table類型高效用法與數據處理實戰

Matlab使用小技巧合集(系列四):Table類型高效用法與數據處理實戰 在科研數據處理和論文寫作過程中,結構化數據的管理極為重要。Matlab的table類型為研究生和科研人員提供了靈活、高效的數據存儲與處理方式,尤其適合實驗結果整理、分組統計、數據預處理等場景。本文將系統介…

STM32的時鐘系統與時鐘樹的配置

STM32的時鐘系統是其微控制器&#xff08;MCU&#xff09;的核心組成部分&#xff0c;負責為CPU、外設和存儲器等模塊提供精確的時序信號。其設計靈活且復雜&#xff0c;通過多級時鐘樹&#xff08;Clock Tree&#xff09;實現時鐘源的選擇、分頻和分配。以下是詳細介紹&#x…

NV 工具metrics分析(ncu, nsys/torch profiler)

以下分析都以A100硬件架構為例; Theoretical Max Active Warps per SM: 64 Register number: 512 (規定每個thread不能超過256) Theoretical Active Warps per SM [warp]&#xff1a;512//registers_per_thread*4, which defines theoretical active warp occupancy Waves P…