樹的BFS:廣度優先搜索,層次遍歷的實現步驟

BFS是樹的經典遍歷方法,按“廣度優先”(層次)訪問節點,核心依賴隊列(FIFO)實現。其步驟爲:初始化隊列(根節點入隊),循環取出隊首節點訪問,將左、右子節點(或子節點自然順序)入隊,直至隊空。 BFS適用於樹的層次關係問題,如計算樹高、判斷完全二叉樹、求根到葉最短路徑等。以二叉樹 `1(2(4,5),3)` 爲例,層次遍歷順序爲1→2→3→4→5。 關鍵點:隊列確保層次順序,子節點入隊順序(左→右),時間複雜度O(n)(n爲節點數),空間複雜度O(n)(最壞隊列存n/2節點)。掌握BFS可高效解決層次問題,爲複雜算法奠基。

閱讀全文
樹的DFS:深度優先搜索,從根到葉的遍歷方法

樹由節點和邊組成,每個節點(除根外)有一個父節點,可有多子節點。DFS(深度優先搜索)是“深入一條路到黑再回溯”的遍歷方法。樹的DFS遍歷含前序(根→左→右)、中序、後序,前序最直接體現根到葉路徑。 遞歸實現前序遍歷:訪問當前節點→遞歸左子樹→遞歸右子樹。以示例樹(根1,左2、右3;2左4、右5)爲例,順序爲1→2→4→5→3。非遞歸用棧:初始化棧入根,循環彈出棧頂訪問,先右後左入棧子節點。 根到葉DFS遍歷用於路徑求和、輸出路徑等問題。遞歸實現直觀,非遞歸用棧模擬適合大數據。掌握前序遍歷是樹結構核心技能。

閱讀全文
哈希函數:哈希函數如何生成哈希值?初學者必知

哈希函數是將任意長度輸入轉爲固定長度哈希值的“翻譯器”,哈希值即數據的“身份證號”。其核心特點:固定長度(如MD5爲32位十六進制字符)、單向不可逆(無法由哈希值反推原數據)、近似唯一(碰撞概率極低)、雪崩效應(輸入微小變化致哈希值鉅變)。生成過程分三步:輸入預處理爲二進制,分段數學運算,合併結果。與加密函數不同,哈希單向無需密鑰,加密可逆需密鑰。應用廣泛:文件校驗(比對哈希值防篡改)、密碼存儲(存哈希值保安全)、數據索引及分佈式系統數據分佈。哈希如數據指紋,關鍵特性使其在安全與校驗中不可或缺。

閱讀全文
插入排序:插入排序如何工作?與冒泡排序對比
2025-12-20 11 閱讀 數據結構

文章介紹了排序的基礎重要性,並聚焦兩種簡單排序算法:插入排序和冒泡排序。 插入排序核心思想是逐步構建有序序列,從第二個元素開始,將每個元素插入到已排序部分的正確位置(類似整理撲克牌)。其平均時間複雜度O(n²),最好情況(數組有序時)爲O(n),空間複雜度O(1),穩定,適用於小規模或接近有序數據。 冒泡排序則通過相鄰元素比較,將大元素逐步“冒”到末尾(如氣泡上浮),每輪確定一個最大元素的位置。平均時間複雜度同樣O(n²),空間複雜度O(1),穩定,但移動元素更多,實際應用較少。 兩者均爲O(n²)複雜度,插入排序更高效,尤其數據接近有序時表現更好。理解它們是學習複雜排序算法的基礎。

閱讀全文
二分查找:二分查找的適用場景,零基礎也能學會

這篇文章介紹了二分查找算法,其核心是在有序數組中通過比較中間元素,逐步縮小查找範圍,快速定位目標。它適用於有序、大數據量、靜態(少修改)且需快速查找的場景,如字典或配置文件。 查找過程通過左右指針`left`和`right`確定中間值`mid`,根據目標與中間值的大小調整指針:若中間值等於目標則找到;若目標更大,右移`left`;若更小,左移`right`,直至找到或範圍無效。 Python迭代實現的核心代碼通過`left <= right`循環,計算`mid = (left + right)//2`,邊界處理確保數組爲空或目標不存在時返回-1。時間複雜度爲O(log n)(每次範圍減半),空間複雜度爲O(1)(僅用常數變量)。 關鍵細節包括處理重複元素需擴展遍歷,單元素數組直接判斷,找不到目標返回-1。二分查找的“減治”思想高效解決有序大數據的快速查找問題,是算法基礎中的重要工具。

閱讀全文
鄰接矩陣:圖的另一種表示方法,優缺點對比

鄰接矩陣是圖的一種基礎表示方式,本質爲n×n二維數組,行與列對應圖的頂點,元素值表示頂點間邊的存在性或權重。無向圖中,元素1表示有邊,0表示無邊;有權圖則直接存儲權重值。 其優點:一是判斷邊存在僅需O(1)時間,計算頂點度高效(無向圖行和,有向圖行/列分別對應出/入度);二是適合稠密圖(邊數接近n²),空間利用率高,且實現簡單,便於初學者理解。 缺點:空間複雜度爲O(n²),稀疏圖時浪費大量空間;遍歷鄰接頂點需O(n)時間,效率低於鄰接表;動態調整邊數靈活性不足。 總結:鄰接矩陣以空間換時間,適合稠密圖、需頻繁查詢邊或計算度的場景,不適合稀疏圖或需頻繁遍歷鄰接頂點的場景,是理解圖結構的基礎工具。

閱讀全文
並查集:並查集是什麼?解決“朋友關係”問題的方法

並查集是管理元素分組的高效數據結構,核心解決“合併組”(Union)和“查詢是否同組”(Find)問題,適用於快速判斷元素是否屬於同一集合的場景。其底層以parent數組維護父節點關係,每組視爲一棵樹,根節點爲組代表,初始各元素自成一組。 關鍵優化是**路徑壓縮**(查詢時壓縮路徑,使節點直接指向根)和**按秩合併**(小樹依附大樹,避免樹退化爲鏈表),確保操作接近常數時間複雜度。核心方法`find`(查找根節點並壓縮路徑)和`union`(合併兩組,小樹根指向大樹根)實現高效分組。 應用廣泛,如網絡連接判斷、家族關係查詢、最小生成樹(Kruskal算法)及等價類問題等,是處理分組場景的簡潔強大工具。

閱讀全文
前綴和:前綴和數組如何快速計算區間和?

前綴和數組是一種用於快速計算區間和的輔助數組。定義爲:原數組A的前綴和數組S,其中S[0]=0,S[k](k≥1)是A[1]到A[k]的和,即S[k] = S[k-1] + A[k]。例如原數組A=[1,2,3,4,5],其前綴和數組S=[0,1,3,6,10,15]。 計算區間和的核心公式是:原數組從第i個到第j個元素的和 = S[j] - S[i-1]。例如計算A[2]到A[4]的和,用S[4]-S[1]=10-1=9,結果正確。 優勢在於:預處理S數組需O(n)時間,每次區間和查詢僅需O(1)時間,總複雜度O(n+q)(q爲查詢次數),遠快於直接計算的O(qn)。需注意索引對齊(如原數組從0開始時公式調整)、區間合法性及空間換時間的特點。 前綴和數組通過“提前累積”實現

閱讀全文
動態規劃:動態規劃入門,斐波那契數列的高效解法

斐波那契數列定義爲f(0)=0,f(1)=1,n>1時f(n)=f(n-1)+f(n-2)。直接遞歸計算時,因重複計算過多,時間複雜度達O(2^n),效率極低。 動態規劃通過空間換時間優化:一是記憶化遞歸,用備忘錄數組存儲已計算結果,每個子問題僅算一次,時間與空間複雜度均爲O(n);二是遞推法,僅用兩個變量迭代計算,時間O(n)、空間O(1),爲最優解。 動態規劃核心特性是重疊子問題(子問題重複出現)與最優子結構(當前解依賴子問題解)。其本質是通過存儲子問題結果避免重複計算,斐波那契是經典入門案例,掌握後可推廣至爬樓梯等同類問題。

閱讀全文
平衡二叉樹:爲什麼需要平衡?旋轉操作簡單講

二叉搜索樹(BST)因極端插入可能退化爲鏈表,操作複雜度升至O(n)。平衡二叉樹通過**平衡因子**(節點左右子樹高度差)控制平衡,要求平衡因子爲-1、0或1。當不平衡時,通過**旋轉操作**(LL右旋、RR左旋、LR先左旋後右旋、RL先右旋後左旋)調整結構,使樹高保持log n級別,確保查找、插入、刪除等操作複雜度穩定在O(log n)。旋轉本質是調整支點,恢復樹的平衡結構。

閱讀全文
圖:圖的基本概念,鄰接表表示法初學者指南

圖由頂點(點)和邊(連接關係)組成,頂點是基本單元,邊可單向(有向圖)或雙向(無向圖),有權圖邊帶權重(如距離),無權圖僅存連接關係。鄰接表是高效表示法,解決鄰接矩陣在稀疏圖(邊遠少於頂點平方)中空間浪費問題,核心是每個頂點對應存儲直接相連頂點的列表。無向圖鄰接表如頂點0連接1、2、3,鄰接表爲[1,2,3];有權圖可存“鄰接點+權重”元組。鄰接表空間複雜度O(V+E)(V頂點數,E邊數),適合稀疏圖,遍歷鄰接點方便,但判斷兩點是否有邊需遍歷鄰接表。掌握鄰接表爲圖遍歷、最短路徑等算法奠定基礎。

閱讀全文
堆:堆的結構與應用,最小堆和最大堆入門

堆是一種特殊的完全二叉樹,核心特點是父節點與子節點滿足大小關係(最小堆父≤子,最大堆父≥子),能高效獲取極值(堆頂爲最小或最大元素),類似優先隊列。其底層爲完全二叉樹,每一層儘量填滿,最後一層從左到右排列。數組存儲時,左子節點索引=2i+1,右子節點=2i+2,父節點=(i-1)//2。基本操作包括插入(末尾添加後上浮)和刪除(堆頂刪除後尾元素頂替,再下沉),時間複雜度均爲O(log n)。堆廣泛用於優先隊列(任務調度)、找第k大元素、哈夫曼編碼等場景,是高效處理極值問題的關鍵結構。

閱讀全文
貪心算法:貪心算法是什麼?找零錢問題實例講解

貪心算法是每步選擇當前最優(局部最優)以期望全局最優的算法,核心是滿足“貪心選擇性質”——每步局部最優能導致全局最優。經典應用如找零錢:以25、10、5、1分硬幣爲例,找67分時,按從大到小逐步取25×2(50分)、10×1(10分)、5×1(5分)、1×2(2分),共6枚,驗證爲最優。其侷限性在於,若問題不滿足貪心選擇性質(如硬幣面額[1,3,4]找6分),貪心可能失效(貪心取4+1+1=3枚,最優爲3+3=2枚)。適用場景包括硬幣面額合理(如25、10、5、1)、活動安排(選最早結束活動)等。總之,貪心算法簡單直觀高效,但僅適用於滿足貪心選擇性質的問題,不保證所有問題全局最優。

閱讀全文
分治算法:分治思想如何解決問題?歸併排序原理

分治算法核心是“分而治之”,通過分解(拆分爲小問題)、解決(遞歸求解子問題)、合併(整合結果)三步處理複雜問題,適合遞歸結構場景。以數組總和計算爲例,分解數組,遞歸求子數組和,合併得總和。 歸併排序是典型應用:先分解數組至單個元素(本身有序),再用雙指針法合併有序子數組。其時間複雜度O(n log n),空間複雜度O(n)(需臨時數組)。 分治通過遞歸簡化問題,歸併排序高效體現其優勢,是理解遞歸、排序等算法的基礎。

閱讀全文
遞歸:遞歸是什麼?用斐波那契數列舉例,初學者也能懂

這篇文章用生活化的例子和經典案例講解了遞歸的概念。遞歸是將大問題分解爲更小的同類問題,直到問題小到可直接解決(終止條件),再通過小問題結果反推大問題結果的方法,核心是“分解”與“終止”。 以斐波那契數列爲例,其遞歸定義爲:F(0)=0,F(1)=1,n>1時F(n)=F(n-1)+F(n-2)。計算F(5)時,需先算F(4)和F(3),依此類推,直到分解到F(0)或F(1)(終止條件),再逐層返回結果。遞歸的關鍵是必須有明確終止條件(如n=0、1),且每次調用規模遞減,否則會無限循環。 Python代碼實現簡潔:`def fibonacci(n): if n==0: return 0; elif n==1: return 1; else: return fibonacci(n-1)+fibonacci(n-2)`。遞歸代碼優雅但計算大數字(如F(100))時效率低於迭代法,體現了“以退爲

閱讀全文
查找算法:順序查找和二分查找的區別,哪個更快?

文章介紹了兩種基礎查找算法:順序查找和二分查找,用於解決從數據中定位特定元素的問題。 順序查找(線性查找)原理是逐個比較元素,無需數據有序,時間複雜度O(n)(n爲數據量),優點是簡單,缺點是效率低,適合小數據量或無序數據。 二分查找(折半查找)要求數據有序,通過分半比較縮小範圍,時間複雜度O(log n),效率高(如n=1000時僅需約10次),但需處理邊界條件,適合大數據量有序數據。 兩者對比:順序查找無需有序、實現簡單但效率低;二分查找需有序且複雜度高但速度快。選擇依據爲數據規模和有序性:有序大數據用二分,無序小數據用順序。

閱讀全文
排序算法:冒泡排序入門,步驟詳解+代碼示例

冒泡排序是計算機科學中最簡單的排序算法之一,核心思想是通過重複比較相鄰元素並交換位置,使大元素逐步“冒泡”到數組末尾。其基本步驟爲:外層循環控制n-1輪比較(每輪確定一個大元素位置),內層循環從第一個元素開始,依次比較相鄰元素,若前大後小則交換;優化項爲若某輪無交換,說明數組已有序,可提前終止。 時間複雜度上,最壞情況(完全逆序)爲O(n²),最好情況(已排序)爲O(n),空間複雜度爲O(1)(僅需常數額外空間)。該算法實現簡單、易於理解,適合小規模數據排序,是排序算法的入門基礎。

閱讀全文
哈希表:哈希表如何存儲數據?衝突解決方法圖解

哈希表是通過哈希函數將鍵映射到數組桶位置的鍵值對存儲結構,實現O(1)級別的高效查找、插入與刪除。其底層爲數組,鍵經哈希函數(如“鍵%數組長度”)轉換爲數組索引(桶位置),直接存儲對應的值。 當不同鍵哈希值相同時會發生衝突(如學號12和22在數組長度10時均%10得2)。經典解決方法有二:鏈地址法(每個桶存鏈表,衝突元素掛在鏈表尾部),實現簡單但需額外空間;開放定址法(線性探測下一個空桶,如衝突位置h→h+1→h+2...),純數組操作但可能形成聚集。 哈希表核心在於哈希函數、衝突處理邏輯,是數據結構學習的基礎。

閱讀全文
二叉樹:二叉樹的三種遍歷方式,遞歸實現超簡單

這篇文章介紹了二叉樹的三種經典遍歷方式(前序、中序、後序),基於遞歸實現,核心是明確根節點的訪問位置。 二叉樹每個節點最多有左右子樹,遍歷即按特定順序訪問節點。遞歸是關鍵,類似“套娃”,函數自調用且範圍縮小,直到遇到空節點終止。 三種遍歷順序區別:前序(根→左→右)、中序(左→根→右)、後序(左→右→根)。以示例樹(根1,左2,右3;2的左4,右5)爲例: - 前序遍歷結果:1 2 4 5 3; - 中序遍歷結果:4 2 5 1 3; - 後序遍歷結果:4 5 2 3 1。 遞歸實現核心:終止條件(空節點返回)+ 按遍歷順序遞歸左右子樹。通過明確根位置和遞歸邏輯,可清晰理解遍歷過程。

閱讀全文
樹:樹結構是什麼?用生活例子輕鬆理解

這篇文章用生活類比講解數據結構中的“樹”。核心是樹與生活中的樹類似:有根節點(起點)、子節點/父節點(分支與源頭)、葉子節點(無後代)及子樹(節點與後代),具有非線性、分支型、層級分明的特點。 與線性鏈表(單一路徑)不同,樹可多分支(如根節點分多個子節點)。生活中樹結構無處不在:家庭關係以長輩爲根,公司架構以CEO爲根,電腦文件系統以磁盤爲根,均體現層級分支。 樹的核心優勢是高效處理層級化分支問題,如數據庫索引、導航路徑規劃、遊戲場景構建等。理解樹結構能掌握分支型問題的處理思維,生活中家庭、公司、文件系統都是樹的典型應用。

閱讀全文
隊列:隊列的“先進先出”如何實現?簡單例子說明

隊列是遵循“先進先出”(FIFO)原則的數據結構,僅能在隊尾入隊、隊頭出隊,核心概念包括隊頭(最早元素)、隊尾(最晚元素),基本操作爲入隊(Enqueue)和出隊(Dequeue)。 以數組實現爲例,需front(隊頭指針)、rear(隊尾指針)及固定容量數組。隊空條件爲front == rear,隊滿爲rear == max_size;入隊時rear後移存儲元素,出隊時front後移取出元素。 實例演示:容量5的隊列,初始front=0、rear=0;入隊1、2、3後rear=3,隊列[1,2,3];出隊1(front=1),再入隊4(rear=4);入隊5後隊列滿,出隊2(front=2),最終隊列[3,4,5]。 應用場景包括任務調度、廣度優先搜索(BFS)、打印機隊列、網絡請求等,在數據處理和任務排隊中作用關鍵。

閱讀全文
棧:棧的“後進先出”是什麼意思?原理圖解

這篇文章以“疊盤子”爲例,解釋了數據結構“棧”的核心概念。棧是隻能從一端(棧頂)進行插入和刪除操作的線性表,另一端爲棧底,其核心特性是“後進先出”(LIFO)——最後放入的元素最先被取出。 棧的基本操作包括:入棧(push,添加元素到棧頂)、出棧(pop,移除並返回棧頂元素)、查看棧頂(top)和判空(empty)。例如,疊盤子時,新盤子放在最上面(入棧),拿取時必須先取最上面的(出棧),符合LIFO。 棧在生活與編程中廣泛應用:括號匹配(用棧記錄左括號,遇右括號彈出匹配)、函數調用棧(後調用的函數先返回)、瀏覽器後退功能(依次彈出最近訪問的網頁)等。理解棧的“LIFO”特性,能幫助解決遞歸、動態規劃等問題,是數據結構的基礎工具。

閱讀全文
鏈表:單鏈表與雙鏈表的區別,初學者一看就會

文章以遊戲玩家列表存儲爲例,說明鏈表解決數組刪除中間元素需移動節點的問題。鏈表是由節點組成的線性結構,節點含數據域和指針域,非連續內存存儲,插入刪除僅需修改指針。 單鏈表最簡單,節點僅含next指針,單向遍歷(從頭至尾),插入刪除需先找前驅節點改指針,省內存,適合單向場景(如隊列)。 雙鏈表節點多一個prev指針,支持雙向遍歷,插入刪除直接通過prev/next指針操作,無需找前驅,內存稍高,適合雙向操作(如瀏覽器歷史、通訊錄)。 單雙鏈表對比:單鏈表結構簡單省內存,雙鏈表功能全但稍佔內存。根據需求選擇:單向用單鏈表,雙向或頻繁操作用雙鏈表。

閱讀全文
數組:爲什麼數組是數據結構的基石?零基礎必學

這篇文章介紹了數組作爲數據結構基礎的核心地位。數組是相同類型元素的序列,通過索引(從0開始)實現隨機訪問,具有簡單直觀、連續存儲和高效索引訪問的特點。它是棧、隊列、哈希表等複雜結構的基礎(如棧用數組實現後進先出,隊列用循環數組實現先進先出),也是二維數組(矩陣)的基礎。數組支持遍歷、查找、排序等基礎操作,且隨機訪問時間複雜度爲O(1),遠超鏈表的O(n)。但它存在固定大小(靜態數組)和插入刪除效率低(需移動元素)的侷限。總之,數組是數據結構的“入門鑰匙”,掌握它能爲後續學習複雜結構和算法奠定基礎。

閱讀全文
C++靜態成員:類的共享變量與函數

這篇文章介紹了C++中靜態成員(變量和函數)的概念、用法及注意事項。 靜態成員用於解決普通成員變量無法共享數據的問題:靜態成員變量(`static`修飾)屬於整個類,存儲在全局數據區,所有對象共享,需在類外初始化(如`int Student::count = 0;`),可通過類名或對象訪問(如`Student::count`)。示例中`Student`類用靜態變量`studentCount`統計對象數量,構造時加1、析構時減1,展示共享特性。 靜態成員函數同樣用`static`修飾,屬於類而非對象,無`this`指針,只能訪問靜態成員,可通過類名或對象調用(如`Student::getCount()`)。 注意事項:靜態成員變量需類外初始化;靜態函數不能直接訪問非靜態成員;避免過度使用靜態成員以降低耦合。 總結:靜態成員實現類共享數據與工具函數,提升數據一致性,適用於全局狀態(如計數器),但需合理控制使用場景。

閱讀全文