数据结构与算法 —— 链表linked list(01)
鏈表(維基百科)
鏈表(Linked list)是一種常見的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),是一種線性表,但是并不會按線性的順序存儲數(shù)據(jù),而是在每一個節(jié)點(diǎn)里存到下一個節(jié)點(diǎn)的指針(Pointer)。由于不必須按順序存儲,鏈表在插入的時候可以達(dá)到O(1)的復(fù)雜度,比另一種線性表順序表快得多,但是查找一個節(jié)點(diǎn)或者訪問特定編號的節(jié)點(diǎn)則需要O(n)的時間,而順序表相應(yīng)的時間復(fù)雜度分別是O(logn)和O(1)。使用鏈表結(jié)構(gòu)可以克服數(shù)組鏈表需要預(yù)先知道數(shù)據(jù)大小的缺點(diǎn),鏈表結(jié)構(gòu)可以充分利用計(jì)算機(jī)內(nèi)存空間,實(shí)現(xiàn)靈活的內(nèi)存動態(tài)管理。但是鏈表失去了數(shù)組隨機(jī)讀取的優(yōu)點(diǎn),同時鏈表由于增加了結(jié)點(diǎn)的指針域,空間開銷比較大。在計(jì)算機(jī)科學(xué)中,鏈表作為一種基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)可以用來生成其它類型的數(shù)據(jù)結(jié)構(gòu)。鏈表通常由一連串節(jié)點(diǎn)組成,每個節(jié)點(diǎn)包含任意的實(shí)例數(shù)據(jù)(data fields)和一或兩個用來指向上一個/或下一個節(jié)點(diǎn)的位置的鏈接("links")。鏈表最明顯的好處就是,常規(guī)數(shù)組排列關(guān)聯(lián)項(xiàng)目的方式可能不同于這些數(shù)據(jù)項(xiàng)目在記憶體或磁盤上順序,數(shù)據(jù)的訪問往往要在不同的排列順序中轉(zhuǎn)換。而鏈表是一種自我指示數(shù)據(jù)類型,因?yàn)樗赶蛄硪粋€相同類型的數(shù)據(jù)的指針(鏈接)。鏈表允許插入和移除表上任意位置上的節(jié)點(diǎn),但是不允許隨機(jī)存取。鏈表有很多種不同的類型:單向鏈表,雙向鏈表以及循環(huán)鏈表。單向鏈表(又名單鏈表、線性鏈表)是鏈表的一種,其特點(diǎn)是鏈表的鏈接方向是單向的,對鏈表的訪問要通過從頭部開始,依序往下讀取.
定義
我們來看一下單向鏈表的定義實(shí)現(xiàn):
class ListNode(object):def __init__(self, value):self.value = valueself.next = None一個節(jié)點(diǎn)有value的屬性定義該節(jié)點(diǎn)的值,還有一個next的指針,指向下一個節(jié)點(diǎn),類似于1>2>4>5>6>3這樣。
操作
單向鏈表的操作主要有:添加一個節(jié)點(diǎn),刪除一個節(jié)點(diǎn),遍歷一條鏈表,具體的實(shí)現(xiàn)如下:
def add(pre, new_node):"""pre節(jié)點(diǎn)后面插入一個新的節(jié)點(diǎn):param pre: pre節(jié)點(diǎn):param new_node: 新插入的節(jié)點(diǎn):return:"""new_code.next = pre.nextpre.next = new_nodedef delete(pre):"""pre節(jié)點(diǎn)的后面刪除一個節(jié)點(diǎn):return:"""if pre.next:pre.next = pre.next.nextdef traverse(head):while head:print(head.value)head = head.next在pre節(jié)點(diǎn)后面插入一個節(jié)點(diǎn):只需要把新節(jié)點(diǎn)的指針指向pre節(jié)點(diǎn)指針指向的節(jié)點(diǎn),把pre節(jié)點(diǎn)的指針指向新節(jié)點(diǎn)。
在pre節(jié)點(diǎn)后面刪除一個節(jié)點(diǎn):只需要把pre節(jié)點(diǎn)的指針指向pre節(jié)點(diǎn)的指針的指針節(jié)點(diǎn)(要注意pre節(jié)點(diǎn)的指針不為None)
?題目
我們來看一個關(guān)于鏈表的一個算法題,來自于leetcode:
刪除鏈表中的元素
刪除鏈表中等于給定值?val?的所有元素。
示例
給定:?1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6,?val?= 6
返回:?1 --> 2 --> 3 --> 4 --> 5
分析:一般來講,我們首先會考慮到遍歷一下這個鏈表,移除掉value值等于給定val的節(jié)點(diǎn)就好。但是這里要返回一個新的鏈表,我們知道,對于單向鏈表,我們只能知道當(dāng)前元素的后置節(jié)點(diǎn),而不知道當(dāng)前元素的前置節(jié)點(diǎn)。所以我們要構(gòu)建一個前置節(jié)點(diǎn)。
看代碼:
def removeElements(head, val):""":param head: listNode:param val: int:return: listNode"""dump = ListNode(-1)dump.next = headcur = headpre = dumpwhile cur:if cur.value == val:pre.next = cur.nextelse:pre = pre.nextcur = cur.nextreturn dump.next我們構(gòu)建一個dump節(jié)點(diǎn)作為第一個節(jié)點(diǎn),cur節(jié)點(diǎn)為當(dāng)前循環(huán)的節(jié)點(diǎn),pre節(jié)點(diǎn)為cur節(jié)點(diǎn)的前置節(jié)點(diǎn)。
當(dāng)前節(jié)點(diǎn)的value為給定val的時候,把當(dāng)前cur的前置節(jié)點(diǎn)pre指針指向cur的后置節(jié)點(diǎn),也就是cur.next。然后接著遍歷這個鏈表。
由于第一個節(jié)點(diǎn)dump是我們自己構(gòu)造的(我用的值是-1,你可以用其他不為val的值,一般使用-1),它的next是給出的head,我們只是對head做了調(diào)整。所以最后新的列表就是dump.next,也就是調(diào)整后的head。
?
學(xué)習(xí)技術(shù)交流群:226704167,愿和各位一起進(jìn)步!
?
轉(zhuǎn)載于:https://www.cnblogs.com/lip0121/p/8668023.html
總結(jié)
以上是生活随笔為你收集整理的数据结构与算法 —— 链表linked list(01)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 驻马店看多囊卵巢最好的医院推荐
- 下一篇: 蒜头君吃桃