hello,我是 snow,因我的緣由在專欄中消失了很長時間,想了不少不應想的,作了不少不應作的。偶爾發一些沸點來刷存在感。感謝掘金,相比朋友圈我更喜刷沸點,由於在這裏我能找到共鳴。好了,忽略。前端
今天來了解下數據結構中的鏈表含義。數組
數組是須要一塊連續的內存空間來存儲,對內存的要求比較高。 而鏈表卻相反,它並不須要一塊連續的內存空間。鏈表是經過指針將一組零散的內存塊串聯在一塊兒。數據結構
相比數組,鏈表是一種稍微複雜一點的數據結構。固然,二者沒有好壞之分,各有各的優缺點。性能
數組能夠快速的查找某個元素,可是在插入和刪除時就要移動大量元素。緣由就在於相鄰元素的存儲位置也具備鄰居關係。他們的編號是 0,1,2,3,4,...,n,它們在內存中的位置也是緊挨着的,中間沒有空隙,因此就沒法快速添加元素。而當刪除後,當中就會留出空隙,天然須要彌補。指針
因此咱們須要這樣一種數據結構: 咱們反正也是要讓相鄰元素間留有足夠餘地,那乾脆全部的元素都不要考慮相鄰位置了,哪有空位就到哪裏,只是讓每一個元素知道它下一個元素的位置在哪裏。咱們能夠在第一個元素時,就知道第二個元素的位置在哪;在第二個元素時,再找到第三個元素的位置。這樣,全部的元素均可以遍歷而找到。cdn
所以,爲了表示每一個數據元素 n 和後繼元素 n+1 之間的邏輯關係,對數據元素 n 來講,除了存儲自己的信息以外,還須要存儲一個指示其後繼的信息。咱們把存儲元素的域稱之爲 數據域,把存儲直接後繼位置的域稱之爲 指針域。指針域中存儲的信息稱作 指針或鏈。這兩部分信息組成數據元素 n 的存儲映像,稱爲 結點。blog
而由 n 個結點鏈結成一個鏈表,稱之爲 鏈式存儲結構。遊戲
最簡單最經常使用的是 單鏈表,此鏈表的每一個結點只包含一個指針域。內存
如上圖,就是一個簡單的單鏈表示意圖。其中有兩個結點是比較特殊的。他們分別是第一個結點和最後一個節點。咱們習慣性地把第一個結點叫作頭結點,把最後一個結點叫作尾結點。頭結點是用來記錄鏈表的基地址。有了它,咱們就能夠遍歷獲得整條鏈表。而尾結點特殊地方它的指針不是指向下一個地方,而是指向一個空地址 NULL,表示這是鏈表上最後一個結點。開發
咱們能夠判斷當前結點的 next 是否爲空,就知道循環是否結束。
就像一家三口並排的手牽手去逛街,爸爸牽着媽媽,媽媽牽着孩子。此時的爸爸就能夠當作頭結點,而孩子就是尾結點。
與數組同樣,鏈表也支持數據的增刪改查。 對比插入和刪除操做,爲了保持內存數據的連續性,數據須要進行大量的數據搬移工做,因此時間複雜度爲 O(n)。而在鏈表中插入和刪除數據,並不須要擔憂此事,由於鏈表的存儲空間自己就不是連續的。因此,在鏈表中插入和刪除一個數據是很是快速的。
對比查找操做,鏈表就沒有數組那麼高效了。由於鏈表中的數據並不是連續存儲的,因此沒法像數組那樣,根據下標等方法查找,鏈表須要根據指針依次遍歷,直到找到對應的結點。
屏幕前的你都還很年輕,不會以爲日月如梭。可上了點年紀的人,好比我---的父輩們,就會經常感嘆,要是能回到從前該多好,向天再借 500 年可好。也有人說,所謂的成功男人就是 3 歲時不尿褲子,5 歲時能本身吃飯....80 歲能本身吃飯,90 歲能不尿褲子。人生是否是在循環呢。
對於單鏈表,因爲每一個結點只存儲了向後的指針,到了尾結點就中止了向後鏈的操做。這樣,當中的某一結點就沒法找到它的前驅結點了,就如上圖同樣,不能回到從前了。
好比說,咱們的市場銷售同窗家在北京,須要常常到上海出差。行程就是去兩地之間的各個城市。從北京出發,乘坐高鐵通過多個城市後,再乘坐灰機返回北京。
北京 --> 濟南 --> 蚌埠 --> 南京 --> 蘇州 --> 上海
有一次,他先到南京開會,接下來還要把以上的城市再走一遍。此時有人對他說,不行,你得從上海開始,由於北京是第一站。這時他會對這人說什麼?神經病。他從南京開始,到蘇州,上海,而後再回北京而後去濟南的幾個城市就能夠了。顯然這表示是你從當中某一個結點開始遍歷整個鏈表,這是原來的單鏈表結構不能解決的問題。
事實上,把北京和上海連起來,行成一個環就解決了前面所面臨的問題。這就是 循環鏈表。
將單鏈表中尾結點的指針由空指針指向頭節點,就使整個單鏈表造成一個環,這種頭尾相接的單鏈表就簡稱爲循環鏈表。
其實循環鏈表和單鏈表的主要差別就在於循環的判斷條件上,原來是判斷當前結點的 next 是否爲空,如今則是判斷當前結點的 next 是否等於頭結點。
就像一家三口圍成一個圈作遊戲,爸爸牽着媽媽,媽媽牽着孩子,孩子又牽着爸爸。
今天咱們銷售又得出差了,平時都是從北京一路停留到上海的。但是這一次,他得先到上海開會,開完後,而後又得須要例行公事,走訪各個城市,此時他該怎麼辦? 這個時候,那人又出主意了,你能夠先飛回北京,而後再一路乘坐火車走遍這幾個城市。
哎,人生中總會避免不了這樣給你出餿主意的人存在。哪有這麼麻煩,他一路再乘坐高鐵回去不就完事了嘛。
就如單鏈表,老是從頭至尾找結點,難道就不能夠正反遍歷嗎?
因此這個時候雙向鏈表就登場了。雙向鏈表是在單鏈表的每一個結點中,再設置一個指向其前驅結點的指針域。因此在雙向鏈表中的結點都有兩個指針域,一個指向直接後繼,另外一個指向直接前驅。
從上圖中能夠看出來,雙向鏈表須要額外的兩個空間來存儲後繼結點和前驅結點的地址。因此,若是存儲一樣多的數據,雙向鏈表要比單鏈表佔用更多的內存空間。雖然兩個指針比較浪費存儲空間,可是能夠支持雙向遍歷,這樣也帶來了雙向鏈表操做的靈活性。
既然單鏈表能夠有循環鏈表,那麼雙向鏈表固然也能夠是循環鏈表。你能夠停下來想一想雙向循環鏈表長什麼樣子。
《大話數據結構》
各位大佬,初碰水面,不喜勿噴。若有錯誤,還請指出,謝謝。
下一篇總結下如何寫好鏈表代碼。
咱們下期見。