單鏈表的冒泡排序實現:從原理到代碼詳解

單鏈表的冒泡排序實現:從原理到代碼詳解

引言

單鏈表作為一種常見的數據結構,其排序操作因節點無法隨機訪問(需通過指針遍歷)而與數組排序存在差異。冒泡排序因其實現簡單、無需額外空間(僅需指針操作),成為單鏈表排序的常用選擇。本文將詳細解析單鏈表冒泡排序的原理、實現細節、優化點及常見錯誤,幫助讀者徹底掌握這一算法。

一、單鏈表冒泡排序的核心思路

冒泡排序的核心是重復遍歷鏈表,每次比較相鄰節點的值,若順序錯誤則交換,直至整個鏈表有序。針對單鏈表的特點,算法需解決兩個關鍵問題:

  1. 如何標記每趟排序的終點(避免重復比較已排好的尾部元素);
  2. 如何檢測鏈表是否已提前有序(減少無效遍歷)。

二、算法關鍵變量解析

在實現代碼中,三個指針變量是核心,需明確其作用:

變量名作用
pPre指向當前比較的前一個節點
pCur指向當前比較的后一個節點(與pPre相鄰)
pTail標記每趟排序的終點(初始為NULL,每趟排序后指向當前趟的最后一個節點,下一趟排序僅需遍歷到pTail前)

此外,IsChange變量用于標記當前趟是否發生過交換:若未發生交換,說明鏈表已完全有序,可直接退出排序,避免后續無效操作。

三、代碼實現與詳細注釋

// 單鏈表冒泡排序函數(升序)
// plist為鏈表頭指針
void BubbleSort(pList plist) {  pNode pCur = NULL;    // 當前節點指針pNode pPre = NULL;    // 當前節點的前一個節點指針pNode pTail = NULL;   // 每趟排序的終點指針(初始為NULL,即鏈表末尾)// 邊界條件:空鏈表或只有一個節點,無需排序if (plist == NULL || plist->next == NULL) {  return;  }// 外層循環:控制排序趟數(每趟將最大元素"冒泡"到尾部)// 當plist == pTail時,說明所有元素已排序完成while (plist != pTail) {  int IsChange = 0;  // 標記當前趟是否發生交換(0:未交換,1:已交換)pPre = plist;      // 每趟開始時,pPre從鏈表頭出發pCur = pPre->next; // pCur指向pPre的下一個節點// 內層循環:控制每趟的比較次數(遍歷到pTail前)while (pCur != pTail) {  // 若前一個節點值大于后一個節點值,交換數據(升序排序)if (pPre->data > pCur->data) {  // 修正原代碼的交換錯誤:正確的交換邏輯int tmp = pPre->data;  pPre->data = pCur->data;  pCur->data = tmp;  IsChange = 1;  // 標記發生交換}// 移動指針,繼續比較下一對相鄰節點pPre = pPre->next;  pCur = pCur->next;  }// 若當前趟未發生交換,說明鏈表已完全有序,直接退出if (!IsChange) {  return;  }// 更新pTail為當前趟的最后一個節點(下一趟無需比較到此節點)pTail = pPre;  }
}

四、關鍵邏輯詳解

1. 為什么需要pTail

在數組冒泡排序中,每趟排序后最大元素會 “浮” 到末尾,下一趟可減少一次比較。單鏈表中,pTail的作用類似:每趟排序后,pTail指向當前趟的最后一個節點(即該趟確定的最大元素),下一趟只需遍歷到pTail之前,減少無效比較次數,優化效率。

2. IsChange的作用是什么?

若某趟排序中未發生任何交換(IsChange=0),說明鏈表已完全有序,可直接退出排序。例如,初始鏈表為1->2->3->4,第一趟遍歷后IsChange=0,算法直接返回,避免后續n-1趟的無效遍歷,最佳情況下時間復雜度可優化至 O (n)

五、時間復雜度與空間復雜度

  • 時間復雜度
    • 最壞情況(鏈表逆序):需n-1趟,每趟比較n-i次,總復雜度為O(n2)
    • 最好情況(鏈表已有序):僅需 1 趟比較,復雜度為O(n)
  • 空間復雜度:僅使用常數個指針變量(pCurpPrepTail等),復雜度為O(1)

六、示例演示

以初始鏈表3->1->4->2為例,演示排序過程:

  1. 第一趟排序
    • 初始pTail=NULLpPre=3pCur=1
    • 比較3>1:交換后鏈表為1->3->4->2IsChange=1
    • 移動指針:pPre=3pCur=4(3<4,不交換);
    • 繼續移動:pPre=4pCur=2(4>2,交換后鏈表為1->3->2->4IsChange=1);
    • 第一趟結束,pTail=4(指向當前最大元素 4)。
  2. 第二趟排序
    • pTail=4,遍歷至pCur!=4
    • pPre=1pCur=3(1<3,不交換);
    • pPre=3pCur=2(3>2,交換后鏈表為1->2->3->4IsChange=1);
    • 第二趟結束,pTail=3
  3. 第三趟排序
    • pTail=3,遍歷至pCur!=3
    • pPre=1pCur=2(1<2,不交換);
    • 遍歷結束,IsChange=0,算法直接返回。

最終鏈表為1->2->3->4,排序完成。

七、總結

單鏈表的冒泡排序通過指針操作實現,核心在于利用pTail減少無效比較、利用IsChange檢測提前有序,從而優化效率。需注意指針移動邏輯和數據交換的正確性,避免因細節錯誤導致排序失敗。

該算法實現簡單、空間開銷小,適合小規模鏈表排序;若需處理大規模數據,可考慮單鏈表的快速排序等更高效算法。

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

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

相關文章

如何在 Ubuntu 24.04 或 22.04 上安裝和使用 GDebi

APT 是 Ubuntu 上安裝需要外部依賴項的 Debian 包的一種方式,但還有另一種選擇,即 GDebi。本文將介紹如何在 Ubuntu 24.04 上安裝 GDebi,以及如何使用它來安裝 .deb 包所需的依賴項。 什么是 GDebi? GDebi 是默認的 .deb 包安裝器 DPKG 的輕量級替代品。與 DPKG 不同,GD…

俄羅斯方塊游戲開發(面向對象編程)

摘要本設計基于MATLAB面向對象編程技術&#xff0c;開發了一款具備完整游戲邏輯的俄羅斯方塊游戲。通過類封裝實現游戲核心模塊&#xff08;方塊管理、游戲板狀態、碰撞檢測等&#xff09;&#xff0c;采用旋轉矩陣實現方塊變形&#xff0c;結合MATLAB圖形用戶界面&#xff08;…

背包DP之多重背包

背包DP之多重背包一、多重背包基礎認知1.1 問題定義1.2 核心特征二、基礎解法&#xff1a;暴力拆分2.1 核心思路2.2 代碼實現2.3 局限性分析三、優化解法&#xff1a;二進制拆分3.1 優化原理3.2 拆分步驟3.3 代碼實現3.4 復雜度分析四、二進制拆分過程五、多重背包的變種與應用…

Ansible 變量指南:聲明、優先級、作用域與最佳實踐(一)

Ansible 變量的聲明 前言 全面理解 Ansible 變量是編寫高效、可維護 Playbook 的關鍵。由于最近使用 Ansible 比較多&#xff0c;在變量問題上踩了不少坑&#xff0c;也因此對變量的聲明&#xff0c;優先級和作用域有了更深的理解。姑且總結一下&#xff0c;分享給大家&#…

[極客大挑戰 2019]FinalSQL--布爾盲注

直接看題可以看到題目給了提示盲注&#xff01;那么接下來就是尋找注入點了&#xff01;那么不能發現注入點就是id了&#xff01;注入類型為數值型注入&#xff01;這里直接嘗試盲注。但是這里and被過濾了&&也不行。問了幾個師傅說用or&#xff0c;但是空格被過濾了&am…

再談fpga開發(狀態機的應用)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】前面說過&#xff0c;fpga上面最基礎的部分是寄存器&#xff0c;而所有寄存器存在每一個clock下&#xff0c;都有被翻轉的可能性。至于這些寄存器是…

TCP如何解決網絡切換問題

一、傳統TCP的網絡切換問題核心問題&#xff1a;TCP 連接基于四元組&#xff08;源IP、源端口、目的IP、目的端口&#xff09;&#xff0c;IP 變化導致連接失效二、改進方案與技術演進1. MPTCP&#xff08;多路徑TCP&#xff09; - 主流解決方案核心機制&#xff1a;單連接多路…

【Linux】常用命令(一)

【Linux】常用命令 一1. ls1.1 ls -a 顯示所有文件及其目錄1.2 ls -A 不顯示當前目錄和父目錄1.3 ls -d 顯示目錄本身&#xff0c;而不是顯示其內部內容1.4 ls -i 顯示文件的inode屬性信息1.4.1 實際用途場景1.5 ls -l 顯示文件的詳細屬性信息1.6 ls -R 遞歸顯示所有子文件1.7 …

Window 部署 coze-stdio(coze 開發平臺)

參考鏈接 https://github.com/coze-dev/coze-studio/wiki/2.-%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B https://github.com/coze-dev/coze-studio/wiki/3.-%E6%A8%A1%E5%9E%8B%E9%85%8D%E7%BD%AE 環境說明 Docker&#xff1a;28.3.2 系統&#xff1a;Window 11 配置要求 CP…

【Git】Git LFS的使用

一、簡介 Git LFS&#xff08;Git Large File Storage&#xff09;是由 GitHub 開發的一款 Git 擴展工具&#xff0c;旨在幫助開發者更高效地管理倉庫中的大文件。傳統 Git 會將文件的每個版本完整存儲在倉庫歷史中&#xff0c;導致大文件&#xff08;如音頻、視頻、數據集、二…

不坑盒子:Word里1秒制作“花括號”題目,多音字組詞、形近字組詞……

1. 30秒看懂它能干啥 用“不坑盒子”插件&#xff0c;在 Word 里輸入&#xff1a; 樂,l(快樂),yu(音樂);長,chng(長短),zhǎng(長大)點一下【總分關系】&#xff0c;瞬間出現左邊是“樂”右邊并列兩行拼音括號的花括號結構&#xff1b;再點【并列關系】&#xff0c;又能做出只…

Gateway網關層灰度方案—xx互聯網醫院系統灰度發布設計與思路詳解

通過之前技術的積累&#xff0c;終于開始了本文的編寫&#xff0c;如果對灰度、負載均衡、上下文傳遞、網關不太理解&#xff0c;可以先學習博主的以下博客內容。共勉&#xff1a; 企業級 Java 應用灰度發布設計方案與實踐全解析《Spring 中上下文傳遞的那些事兒》 Part 1&…

學習游戲制作記錄(改進投擲劍的行為)7.27

1.實現劍跟隨飛行方向旋轉修改劍的預制體使劍的朝向對準右x軸Sword_Skill_Contorl腳本&#xff1a;private void Update(){transform.right rb.velocity;//時刻更新位置}2.實現劍插入地面或者敵人修改預制體為觸發器Sword_Skill_Contorl腳本&#xff1a;private bool canRotat…

嵌入式軟件面試八股文

目錄 一、指針函數和函數指針 二、指針的大小 三、sizeof 和 strlen 區別 四、數組指針和指針數組 五、C語言里面內存分配的方式 六、struct結構體和union聯合體的區別 八、數組和鏈表的區別 九、寫一個宏這個紅返回輸入參數比較小的一個 十&#xff0c;使用#include<…

Gradle#Plugin

查看任務來自那個插件 /gradlew tasks --all <taskName>Java Plugin Java Library Plugin

滲透高級-----測試復現(第三次作業)

文章目錄測試復現一&#xff0c;環境搭建二&#xff0c;通過VS Code連接cacti三&#xff0c;測試測試復現 一&#xff0c;環境搭建 1&#xff0c;在ubuntu虛擬機上安裝MySql數據庫&#xff1a; apt-get upgrade # 更新apt-get upgrade apt-get update # 更新apt-ge…

LINUX727 磁盤管理回顧1;配置文件回顧

邏輯卷快照 快照為什么這么小RAID 磁盤陣列 raid 0 raid 1 raid5 raid10raid0 raid1 raid5 raid6 raid10 rank;create raid0 mdadm -c /dev/md0 -l 0 -n 2 /dev/sdb3 /dev/sdb4 raid1 mdadm -c /dev/md1 -l 1 -n 2 /dev/sdb5 /dev/sdb6 raid5 mdadm -c /dev/md5 -l 5 -n 3 -x …

【筆記】Einstein關系式 D = ukBT 的推導與應用研究

文章目錄從漲落理論和能量均分定理的數學推導基于平衡統計力學的推導1. 漂移流的來源&#xff1a;Jdrift?μρ?UJ_{drift} -μρ?UJdrift??μρ?U物理機制粒子流的形成2. 擴散流的來源&#xff1a;Jdiffusion?D?ρJ_{diffusion} -D?ρJdiffusion??D?ρ3. 熱平衡要…

AJAX 原理_第一節_XHR 對象

文章目錄1.AJAX原理1.1 初識XML1.2 查詢參數1.3 案例-地區查詢1.4 案例-注冊-設置請求頭1.AJAX原理 1.1 初識XML AJAX原理是什么? XMLHttpRequest對象 XHR對象定義: 通過XMLHttpRequest可以在不刷新頁面的情況下請求特定URL,獲取數據.這允許頁面在不影響用戶操作的情況下,更…

BeautifulSoup 使用詳解與實戰示例

BeautifulSoup 是一個用于解析HTML和XML文檔的Python庫&#xff0c;它能夠將復雜的HTML文檔轉換成一個復雜的樹形結構&#xff0c;使得我們可以輕松地查找和提取所需的內容。下面我將詳細介紹BeautifulSoup的使用流程&#xff0c;并結合實際示例進行說明。一、安裝與基礎使用1.…