資料結構與演算法之連結串列
連結串列的分類:
(1)單鏈表
頭插法:只需要維護一個頭結點即可,常用來模擬堆疊;
尾插法:需要維護頭結點和尾結點,常用來模擬佇列。
(2)雙向連結串列
雙向遍歷,可以用來儲存網頁的歷史記錄等;
(3)迴圈連結串列
經常出現在面試題中,判斷連結串列是否有環。
連結串列的刪除
方式一:維護兩個指標,current(表示當前節點)和previous(表示當前節點的前一個節點)。當current遍歷到要刪除的元素時,執行previous->next = current->next,並刪除current。在刪除時,需要判斷current是否等於head節點。
方式二:維護一個二級指標,Node ** current和一個臨時變數entry。刪除時只需要執行*current = entry -> next. 並刪除entry即可,無需判斷是否為head節點。
基於記憶體池的連結串列
傳統連結串列的缺點:連結串列在插入過程中會呼叫系統函式分配記憶體,然後將該塊記憶體連結到連結串列中。插入操作有三個缺點:
(1)進行頻繁的系統呼叫,會浪費不少時間;
(2)在連結串列節點分配釋放的過程中會產生很多記憶體碎片,不利於分配整塊記憶體;
(3)可能會導致頻繁的cache缺失;
解決方案:
構造一個記憶體池,每次插入都從記憶體池中獲取一個節點,每次刪除都將節點放回記憶體池。這樣做的優點是不存在記憶體碎片,也不進行系統呼叫。
連結串列的反轉(面試常考)
(1)思路一:在從前往後遍歷的過程中進行反轉。維護三個指標,分別指向當前節點以及當前節點的前後節點。
(2)思路二:將第三個節點到第N個節點,依次逐節點插入到第一個節點(head節點)之後,最後將第一個節點挪到新表的表尾。
(3)思路三:遞迴的處理head後面的節點,然後再修改head和head後面節點的指向。
倒序列印連結串列
(1)遞迴:倒序列印意味著先最後的元素,然後依次往前列印,可以用遞迴實現這個過程。遞迴的列印head後面所有的節點,然後列印head節點。
(2)棧模擬:遞迴使用系統棧(活動記錄),我們可以用STL中的棧來模擬上述遞迴過程。首先順序遍歷一遍連結串列,將元素放入堆疊,然後依次出棧列印元素。
判斷連結串列是否有環
(1)如何判斷是否存在環?
解法:設定一對快慢指標,同時從連結串列的頭開始往前遍歷。慢指標一次前進一步,快指標一次前進兩步,如果有環則兩個指標會相遇。
(2)如何知道環的長度?
解法:記錄下問題(1)的碰撞點,快慢指標再從該位置遍歷一遍環。下次碰撞慢指標走過的距離就是環的長度。
(3)如何找出環的連線點在哪裡?
解法:碰撞點到連線點的距離 = 頭指標到連線點的距離,再次從兩點遍歷即可。
(4)帶環連結串列的長度是多少?
解法:問題2+問題3.
間接定址的基本概念
間接定址簡單描述就是二級指標的應用。二級指標有三個含義:指向指標的指標、一維陣列、二維陣列。間接定址在此特指其一維陣列的含義。
間接定址是陣列和連結串列的組合。既保留了陣列的許多優點,又獲得了連結串列的重要特色。首先,可以根據索引在O(1)的時間內訪問每個元素。其次,可以採用二分在對數時間內對一個有序表進行搜尋。最後,在諸如插入和刪除操作期間不必對元素進行實際的移動。間接定址使用指標陣列來跟蹤每一個元素,對元素本身如何分配不設限制(可離散可連續)。
間接定址的應用
(1)記憶體池
自構建等塊記憶體池,每一個指標分別指向每一塊記憶體的首地址。記憶體池可以避免記憶體碎片和系統呼叫。
(2)雜湊連結串列
如果指標指向的元素包含next指標,則間接定址變成了雜湊連結串列。
模擬指標的基本概念
模擬指標簡單描述就是利用陣列的下標當指標。模擬指標的最大用途是解決並查集問題。
(1)實現一:首先構造一個節點陣列,節點包含兩個域:data和link。link域指向陣列中的其他節點。和間接定址有相似之處。
(2)實現二:陣列只包含link域,可以用來模擬樹。
等價類的定義
定義:假定有一個具有n個元素的集合U,另有一個具有r個關係的集合R。如果(a,b)屬於R,則元素a和b是等價的。等價類是指相互等價元素的最大集合。換句話說,將集合U根據關係進行劃分,類內的元素等價,可以看做是一種聚類。
離線等價類:已知n和R,確定所有的等價類。
線上等價類:初始時有n個元素,每個元素都屬於一個獨立的等價類。然後不停的執行Find和Union操作向R中新增新關係。通常被稱為並查集問題。
並查集的基本概念
並查集的操作:
(1)Find:查詢元素a和b是否屬於同一類;
(2)Union:合併元素a和b所在的類。
並查集的實現:
採用方式二的模擬指標。陣列的下標即表示指標,指標的指向使並查集構成了一棵虛擬的森林。但是並查集不關注每棵樹的形狀以及相互指向關係,只關注最終的根節點以及該樹的元素個數或者高度。
並查集的優化:
可以根據重量規則或者高度規則對並查集的操作進行優化。
相關推薦
資料結構與演算法之連結串列篇(上)
連結串列作為一種基礎的資料結構之一,我們會常常使用到它,接下來就讓我們一起學習吧。 1、連結串列的經典應用場景: LRU快取淘汰演算法。 2、快取是一種提高資料讀取效能的技術,在硬體設計、軟體開發中都有著非常廣泛的應用,比如常見的CPU快取、資料庫快取、瀏覽器快取等等。
資料結構與演算法之連結串列篇(下)
Q:如何輕鬆寫出正確的連結串列程式碼? 總結起來,就是投入時間+技巧; 一、投入時間: 只要願意投入時間,大多數人都是可以學會的,比如說,如果你真能花上一個週末或者一整天時間,就去寫連結
資料結構與演算法之連結串列
連結串列的分類:(1)單鏈表頭插法:只需要維護一個頭結點即可,常用來模擬堆疊;尾插法:需要維護頭結點和尾結點,常用來模擬佇列。(2)雙向連結串列雙向遍歷,可以用來儲存網頁的歷史記錄等;(3)迴圈連結串列經常出現在面試題中,判斷連結串列是否有環。連結串列的刪除方式一:維
java版資料結構與演算法—有序連結串列
package com.zoujc.sortLink; /** * 有序連結串列 */ class Link { public int dData; public Link next; public Link(int dd){ dData = d
【資料結構與演算法】連結串列——遞增排序
今天看書時偶然想到的問題,書上是要求將一個數據插入一個有序連結的線性連結串列中, 所以我想先進行連結串列內的資料排序在進行插入資料。 在這裡我只寫了排序的函式。 函式實現: void Sort(LinkList&list, int &n) { f
[一步步學資料結構與演算法 07]-連結串列(下)
一、理解指標或引用的含義 1.含義:將某個變數(物件)賦值給指標(引用),實際上就是就是將這個變數(物件)的地址賦值給指標(引用)。 2.示例: p—>next = q; //表示p節點的後繼指標儲存了q節點的記憶體地址。 p—>next = p—&
資料結構與演算法----雙向連結串列
PS:前面已經說過線性表的兩種表現形式,一種是順序,另一種是鏈式,鏈式的一種普通表現形式就是加入一個指標,前一個的指標指向後一個結點的地址,那麼還有一種形式就是雙向連結串列,裡面又加上了一個指標變數,讓前指標變數指向直接前驅,後指標變數指向直接後繼。 /** * 建立結構體 * */ typedef
【python資料結構與演算法】連結串列——連結串列中環的入口節點、兩個連結串列的第一個公共節點(相交連結串列)
如題,這類問題在LeetCode上和劍指offer上總共有這些涉及: LeetCode:141,142,160 劍指offer:兩個連結串列的第一個公共節點(預設是無環單鏈表)、連結串列中環的入口節點 補充:兩個未知是否有環的單鏈表第一個公共節點 我直接敘述第三個問題,
資料結構與演算法——有序連結串列合併
要求實現一個函式,將兩個連結串列表示的遞增整數序列合併為一個非遞減的整數序列。 #include <stdio.h> #include <stdlib.h> typedef int ElementType; typedef str
js資料結構與演算法--雙向連結串列的實現
雙向連結串列也叫雙鏈表,是連結串列的一種,它的每個資料節點中都有兩個指標,分別指向直接後繼和直接前驅。所以,雙向連結串列中的任意一個節點開始,都可以很方便的訪問它的前驅節點和後繼節點。 雙向連結串列的實現 linkednode.js ,裡面使用了類的繼承extends,使用了super函式。 /**
『資料結構與演算法』連結串列(單鏈表、雙鏈表、環形連結串列)
> 微信搜尋:碼農StayUp > 主頁地址:[https://gozhuyinglong.github.io](https://gozhuyinglong.github.io/) > 原始碼分享:[https://github.com/gozhuyinglong/blog-demos](h
【資料結構與演算法】——連結串列(Linked List)
## 連結串列(Linked List)介紹 > 連結串列是有序的列表,但是它在記憶體中是儲存如下: > > ![](http://itfxsen.oss-cn-chengdu.aliyuncs.com/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%
資料結構與演算法之六 雙向連結串列和迴圈連結串列
視訊課堂https://edu.csdn.net/course/play/7621 在本章中,你將學習: 執行雙鏈接列表 執行迴圈連結列表 應用連結列表以解決程式設計問題 現在,考慮一個示例,您需要以降序的方式顯示這些數字。
考研資料結構與演算法之堆疊的使用(四)連結串列實現的堆疊
還是參考了別人的程式碼,不過比我自己寫出來的確實是要簡潔的多,不過仍然有不規範的地方,但是仍然值得我學習一下,在敲打的時候也是受到了一定的啟發。 #include <stdio.h> #include <stdlib.h> #define FULL
java資料結構與演算法之順序表與連結串列深入分析
關聯文章: 資料結構與演算法這門學科雖然在大學期間就已學習過了,但是到現在確實也忘了不少,因此最近又重新看了本書-《資料結構與演算法分析》加上之前看的《java資料結構》也算是對資料結構的進一步深入學習了,於是也就打算寫一系列的資料結構的博文以便加
JavaScript 資料結構與演算法之美 - 線性表(陣列、棧、佇列、連結串列)
前言 基礎知識就像是一座大樓的地基,它決定了我們的技術高度。 我們應該多掌握一些可移值的技術或者再過十幾年應該都不會過時的技術,資料結構與演算法就是其中之一。 棧、佇列、連結串列、堆 是資料結構與演算法中的基礎知識,是程式設計師的地基。 筆者寫的 JavaScript 資料結構與演算法之美 系列用
資料結構與演算法之五 連結列表
視訊課堂https://edu.csdn.net/course/play/7621 在本章中,你將學習: 認識連結列表的特性 執行單鏈接列表 假定您已經編寫了一個演算法來
資料結構與演算法之美專欄學習筆記-排序(上)
排序方法 氣泡排序、插入排序、選擇排序、快速排序、歸併排序、計數排序、基數排序、桶排序。 複雜度歸類 氣泡排序、插入排序、選擇排序 O(n^2) 快速排序、歸併排序 O(nlogn) 計數排序、基數排序、桶排序 O(n) 演算法的執行效率 1. 最
資料結構與演算法之美專欄學習筆記-排序(下)
分治思想 分治思想 分治,顧明思意就是分而治之,將一個大問題分解成小的子問題來解決,小的子問題解決了,大問題也就解決了。 分治與遞迴的區別 分治演算法一般都用遞迴來實現的。分治是一種解決問題的處理思想,遞迴是一種程式設計技巧。 歸併排序 演算法原理 歸併的思想 先把陣列從中間分
資料結構與演算法之美專欄學習筆記-線性排序
線性排序 線性排序的概念 線性排序演算法包括桶排序、計數排序、基數排序。 線性排序演算法的時間複雜度為O(n)。 線性排序的特點 此3種排序演算法都不涉及元素之間的比較操作,是非基於比較的排序演算法。 對排序資料的要求很苛刻,重點掌握此3種排序演算法的適用場景。 桶排序 演算法