陣列與鍊錶 一文讀懂

2021-09-27 03:55:19 字數 2443 閱讀 2384

資料結構是軟體開發中最基礎的部分了,它體現著我們程式設計的內功。大多數人在正兒八經學習資料結構的時候估計是在大學計算機課上,而在實際專案開發中,反而感覺到用得不多。

其實也不是真的用得少,只不過我們在使用的時候被很多高階語言和框架元件封裝好了,真正需要自己去實現的地方比較少而已。但別人封裝好了不代表我們就可以不關注了,資料結構作為程式設計師的內功心法,是非常值得我們多花時間去研究的,我這就翻開書複習複習。

非線性的:顧名思義,資料之間的關係是非線性的,比如堆、樹、圖

知道了分類,下面我們來詳細看一下「 陣列 」和「 鍊錶 」的原理。

陣列是乙個有限的、型別相同的資料的集合,在記憶體中是一段連續的記憶體區域。

如下圖:

陣列的下標是從0開始的,上圖陣列中有6個元素,對應著下標依次是0、1、2、3、4、5;同時,陣列裡面存的資料的型別必須是一致的,比如上圖中存的都是數字型別。陣列中的全部元素是「連續」的儲存在一塊記憶體空間中的,如上圖右邊部分,元素與元素之間是不會有別的儲存隔離的。另外,也是因為陣列需要連續的記憶體空間,所以陣列在定義的時候就需要提前指定固定大小,不能改變

所以整體而言,陣列的訪問效率高,插入與刪除效率低。不過想改善陣列的插入與刪除效率也是有辦法的,來來來,下面的「 鍊錶 」了解一下。

鍊錶是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過鍊錶中的指標鏈結次序實現的,一般用於插入與刪除較為頻繁的場景。

上圖是「單鏈表」示例,鍊錶並不需要陣列那樣的連續空間,它只需要乙個個零散的記憶體空間即可,因此對記憶體空間的要求也比陣列低。

鍊錶的每乙個節點通過「指標」鏈結起來,每乙個節點有2部分組成,一部分是資料(上圖中的data),另一部分是後繼指標(用來儲存後乙個節點的位址),在這條鏈中,最開始的節點稱為head,最末尾節點的指標指向null。

「 鍊錶 」也分為好幾種,上圖是最簡單的一種,它的每乙個節點只有乙個指標(後繼指標)指向後面乙個節點,這個鍊錶稱為:單向鍊錶,除此之外還有 雙向鍊錶、迴圈鍊錶 等。

雙向鍊錶:

雙向鍊錶與單向鍊錶的區別是前者是2個方向都有指標,後者只有1個方向的指標。雙向鍊錶的每乙個節點都有2個指標,乙個指向前節點,乙個指向後節點。雙向鍊錶在操作的時候比單向鍊錶的效率要高很多,但是由於多乙個指標空間,所以占用記憶體也會多一點。

迴圈鍊錶:

其實迴圈鍊錶就是一種特殊的單向鍊錶,只不過在單向鍊錶的基礎上,將尾節點的指標指向了head節點,使之首尾相連。

例如:插入乙個元素:

既然插入與刪除元素只需要改動指標,無需移動資料,那麼鍊錶的時間插入刪除的時間複雜度為o(1)。不過這裡指的是找到節點之後純粹的插入或刪除動作所需的時間複雜度。

如果當前還未定位到指定的節點,只是拿到鍊錶的head,這個時候要去刪除此煉表中某個固定內容的節點,則需要先查找到那個節點,這個查詢的動作又是乙個遍歷動作了,這個遍歷查詢的時間複雜度卻是o(n),兩者加起來總的時間複雜度其實是o(n)的。

其實就算是已經定位到了某個要刪除的節點了,刪除邏輯也不簡單。以「刪除上圖的e節點」為例,假如當前鍊錶指標已經定位到了e節點,刪除的時候,需要將這個e節點的前面乙個節點h的後繼指標改為指向a節點,那麼e節點就會自動脫落了,但是當前鍊錶指標是定位在e節點上,如何去改變h節點的後續指標呢,對於「單向鍊錶」而言,這個時候需要從頭遍歷一遍整個鍊錶,找到h節點去修改其後繼指標的內容,所以時間複雜度是o(n);但如果當前是「雙向鍊錶」,則不需要遍歷,直接通過前繼指標即可找到h節點,時間複雜度是o(1),這裡就是「雙向鍊錶」相當於「單向鍊錶」的優勢所在。

通過上面的介紹我們可以看到「 陣列 」和「 鍊錶 」各有優勢,並且時間複雜度在不同的操作情況下也不相同,不能簡單一句o(1)或o(n)。所以下面我們找了個常用的演算法題來練習練習。

演算法題:反轉乙個單鏈表

輸入: 1->2->3->4->5->null

輸出: 5->4->3->2->1->null

/**

* definition for singly-linked list.

* public class listnode 

* }*/class solution 

//完成,時間複雜度為o(n)

return pre;}}

以上,就是對「 陣列與鍊錶 」的一些思考。

一文讀懂Nginx

問 nginx的負載均衡演算法有什麼?預設是什麼演算法?答 1 輪詢 按請求的時間輪詢查空閒的後端伺服器 2 指定輪詢機率 機率的原因是後端伺服器的效能不均勻,好的多分點,差的少分點 3 固定ip繫結固定伺服器 預設是加權輪詢,就是優先訪問權重高的伺服器 問 nginx是單執行緒的嗎?答 是單執行緒...

一文讀懂SpringMVC

主要講的是dispatcherservlet這個類 ioc其實是乙個map,工程啟動後掃瞄路徑,根據類的全限定名建立bean 問 怎麼根據路徑找到方法?map還存key為 aaa value為該controller例項 問 autowired原理?自定義註解,在載入的時候,掃瞄controller層...

堆疊 一文讀懂

堆疊 stack 是一種先進後出的 操作受限的線性表,也可以直接稱為棧。可以把棧想象成乙個桶一樣,往這個桶裡面一層一層的放東西,先放進去的在裡面,後放進去的東西依次在外面。但取東西的時候就是先取靠近外面的,再依次一層層取裡面的。這就是 後進先出 last in first out 的原則。因此 棧 ...