算法与数据结构(part6)--单向链表
學習筆記,僅供參考,有錯必糾
參考自:單鏈表頭指針、頭結點、頭元結的辨析
文章目錄
- 算法與數據結構–基于python
- 鏈表
- 為啥需要鏈表
- 什么是鏈表
- 單向鏈表
- 什么是單向鏈表
- 單列表的操作
- 節點的實現
- 單鏈表的實現
- 鏈表與順序表的對比
算法與數據結構–基于python
鏈表
為啥需要鏈表
順序表的構建需要預先知道數據大小來申請連續的存儲空間,而在進行擴充時又需要進行數據的搬遷,所以使用起來不是很靈活;而鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理。
什么是鏈表
鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理,鏈表是一種常見的基礎數據結構,是一種線性表,但是不像順序表一樣連續存儲數據,而是在每一個結點(數據存儲單元)里存放下一個結點的位置信息(即地址)。
單向鏈表
什么是單向鏈表
單向鏈表也叫單鏈表,是鏈表中最簡單的一種形式;它的每個結點包含兩個域,一個信息域(元素域)和一個鏈接域;這個鏈接指向鏈表中的下一個結點,而最后一個結點的鏈接域則指向一個空值。
- 圖示
單鏈表也可以沒有頭結點,如果沒有頭結點的話,那么單鏈表就會變成這樣:
- 關于頭結點
頭結點是為了操作的統一與方便而設立的,放在第一個元素結點之前,其數據域一般無意義(當然有些情況下也可存放鏈表的長度、用做監視哨等等),首元結點也就是第一個元素的結點,它是頭結點后邊的第一個結點,頭結點不是鏈表所必需的。
- 關于頭指針
在線性表的鏈式存儲結構中,頭指針是指鏈表指向第一個結點的指針,若鏈表有頭結點,則頭指針就是指向鏈表頭結點的指針;頭指針具有標識作用,故常用頭指針冠以鏈表的名字;無論鏈表是否為空,頭指針均不為空,頭指針是鏈表的必要元素。
單列表的操作
is_empty() #鏈表是否為空 length() #鏈表長度 travel() #遍歷整個鏈表 append(item) #鏈表尾部添加元素 add(item) #鏈表頭部添加元素 insert(pos, item) #指定位置添加元素 search(item) #查找結點是否存在 remove(item) #刪除結點
節點的實現
class Node:def __init__(self, elem):#初始化數據區self.elem = elem#初始化鏈接區self.next = None
單鏈表的實現
首先,我們參照下圖中的鏈表形式,來構造我們的單鏈表:
同時,我們參照下圖中的尾插法,在我們的鏈表末尾插入數據:
參照下圖中的頭插法,在鏈表頭部添加元素:
參照下圖中的插入法,在鏈表中指定位置插入元素:
參照下圖中的刪除法,在鏈表中刪除某個指定元素:
定義單鏈表:
class SingleLinkedList:def __init__(self):#頭指針self.__head = None#判斷鏈表是否為空def is_empty(self):return self.__head is None#查詢長度def length(self):#判斷是否為空if self.is_empty():return 0else:#定義游標cur = self.__head#計數count = 0while cur != None:cur = cur.nextcount += 1return count#遍歷鏈表def travel(self):if self.is_empty():returnelse:#定義游標cur = self.__headwhile cur != None:#打印數據print(cur.elem, " ")cur = cur.nextprint('')#鏈表尾部添加元素def append(self, item):#定義新節點node = Node(item)#判斷鏈表是否為空if self.is_empty():self.__head = nodeelse:cur = self.__headwhile cur.next!= None:cur = cur.next#while循環結束后,cur到達了最后一個節點cur.next = node#鏈表開頭插入def add(self, item):#新節點node = Node(item)if self.is_empty():self.__head = nodeelse:node.next = self.__headself.__head = node#鏈表中指定位置插入def insert(self, pos, item):#新節點if pos < 0:self.add(item)elif pos > (self.length() - 1):self.append(item)else:node = Node(item)pre = self.__headcount = 0while count < (pos -1):pre = pre.nextcount += 1#下面的兩行代碼順序不可變node.next = pre.nextpre.next = node#查找節點def search(self, item):if self.is_empty():return Falseelse:cur = self.__headwhile cur!= None:if cur.elem == item:return Trueelse:cur = cur.nextreturn False#刪除節點def remove(self,item):if self.is_empty():returnelse:# 定義cur游標cur = self.__head# 定義pre游標pre = None# 查找所有的位置有沒有要刪除的,若有則刪while cur != None:# 判斷cur指向的數據,是否為要刪的數據if cur.elem == item:# 考慮特殊情況,恰好要刪的是第一個元素if cur == self.__head:# 頭結點指向后一個結點self.__head = cur.nextelse:# 刪除pre.next = cur.nextreturnelse:# 移動游標,先移動pre,再移動curpre = curcur = cur.next測試:
if __name__ == "__main__":sll = SingleLinkedList()print(sll.is_empty())print(sll.length())print('-'*20)sll.travel()print('-'*20)sll.append(1)sll.add(2)sll.append(3)sll.travel()print('-'*20)print(sll.is_empty())print(sll.length())print('-'*20)sll.insert(1,'abc')sll.travel()print(sll.search(2))print('-'*20)sll.remove('abc')sll.travel()輸出:
True 0 -------------------- -------------------- 2 1 3 -------------------- False 3 -------------------- 2 abc 1 3 True -------------------- 2 1 3鏈表與順序表的對比
鏈表與順序表各種操作的時間復雜度:
| 訪問元素 | O(n) | O(1) |
| 在頭部插入/刪除 | O(1) | O(n) |
| 在尾部插入/刪除 | O(n) | O(1) |
| 在中間插入/刪除 | O(n) | O(n) |
總結
以上是生活随笔為你收集整理的算法与数据结构(part6)--单向链表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 飚车世界名字246个
- 下一篇: Django从理论到实战(part4)-