鏈表(linked_list)是物理存儲單元上非連續的、非順序的存儲結構,數據元素的邏輯順序是通過鏈表的指針地址實現,每個元素包含兩個結點,一個是存儲元素的數據域 (內存空間),另一個是指向下一個結點地址的指針域。根據指針的指向,鏈表能形成不同的結構,例如單鏈表,雙向鏈表,循環鏈表等。
鏈表通過將鏈點 i 與其鄰居鏈點 i+1 通過指針相關聯,從索引 0 到索引 N-1 對鏈點進行排序。
鏈表分為單鏈表和雙鏈表兩種。在接下來的內容里,我們將逐步介紹單鏈表的具體功能是如何實現的。
1. 創建 Node 類
創建一個 Node 的類,作為基礎數據結構:鏈點,並初始化對應的內參。
具體實現代碼如下:
class Node: def __init__(self, data): self.data = data #表示對應的元素值 self.next = None #表示下一個鏈接的鏈點
2. 創建 Linked_List 類
創建一個 Linked_List 的類,並初始化對應的內參。
具體實現代碼如下:
class Linked_List: def __init__(self): self.head = None #表示鏈表的頭部元素 def initlist(self,data_list): #鏈表初始化函數 self.head=Node(data_list[0]) #創建頭結點 temp=self.head for i in data_list[1:]: #逐個為 data 內的數據創建結點, 建立鏈表 node=Node(i) temp.next=node temp=temp.next
3. 添加 is_empty 函數
添加一個 is_empty 的函數,功能是判斷鏈表是否為空
具體實現代碼如下:
def is_empty(self): return self.Head is None #判斷鏈表是否為空
4. 添加 insert 函數
insert(item) 往鏈表中任意位置添加一個 item 元素
流程如下:
- Vertex vtx = new Vertex(v) 初始化一個新的點
- tail.next = vtx 隊列尾部的后繼是這個新的點
- tail = vtx 然后讓隊列尾部指針指向這個新的點
具體實現代碼如下:
def insert(self,key,value): #鏈表插入數據函數 if key<0 or key>self.get_length()-1: print("insert error") temp=self.head i=0 while i<=key: #遍歷找到索引值為 key 的結點后, 在其后面插入結點 pre=temp temp=temp.next i=i+1 node=Node(value) pre.next=node node.next=temp
5. 添加 remove 函數
remove() 從鏈表中任意位置刪除一個元素
流程如下:
- 先判斷隊列是否為空,為空即退出 dequeue 操作,不為空即繼續后續操作
- temp = head 設置一個 temp 指針,使它的指針指向隊列頭部
- head = head.next 隊列頭部指針,使之指向隊列頭部的后繼(即隊列頭部元素出隊)
- delete temp 刪除 temp 指針
具體實現代碼如下:
def remove(self,key): #鏈表刪除數據函數 if key<0 or key>self.get_length()-1: print("insert error") i=0 temp=self.head while temp !=None: #遍歷找到索引值為 key 的結點 pre=temp temp=temp.next i=i+1 if i==key: pre.next=temp.next temp=None return True pre.next=None
6. 添加其他函數
get_length:獲取鏈表的長度
print_list:遍歷鏈表,並將元素依次打印出來
reverse:將鏈表反轉
具體實現代碼如下:
def get_length(self): #獲取鏈表的長度 temp=self.head #臨時變量指向隊列頭部 length=0 #計算鏈表的長度變量 while temp!=None: length=length+1 temp=temp.next return length #返回鏈表的長度 def print_list(self): #遍歷鏈表,並將元素依次打印出來 print("linked_list:") temp = self.head #臨時變量指向隊列頭部 while temp is not None: print(temp.data) temp = temp.next def reverse(self): #將鏈表反轉 prev = None current = self.head while current: next_node = current.next current.next = prev prev = current current = next_node self.head = prev
基於鏈表的基本功能介紹,我們給出鏈表的完整代碼
在/home/shiyanlou/
下新建一個文件linked_list.py
。
具體實現代碼如下:
class Node: def __init__(self, data): self.data = data self.next = None class Linked_List: def __init__(self): self.head = None def initlist(self,data_list): #鏈表初始化函數 self.head=Node(data_list[0]) #創建頭結點 temp=self.head for i in data_list[1:]: #逐個為 data 內的數據創建結點, 建立鏈表 node=Node(i) temp.next=node temp=temp.next def is_empty(self): #判斷鏈表是否為空 if self.head.next==None: print("Linked_list is empty") return True else: return False def get_length(self): #獲取鏈表的長度 temp=self.head #臨時變量指向隊列頭部 length=0 #計算鏈表的長度變量 while temp!=None: length=length+1 temp=temp.next return length #返回鏈表的長度 def insert(self,key,value): #鏈表插入數據函數 if key<0 or key>self.get_length()-1: print("insert error") temp=self.head i=0 while i<=key: #遍歷找到索引值為 key 的結點后, 在其后面插入結點 pre=temp temp=temp.next i=i+1 node=Node(value) pre.next=node node.next=temp def print_list(self): #遍歷鏈表,並將元素依次打印出來 print("linked_list:") temp=self.head new_list=[] while temp is not None: new_list.append(temp.data) temp=temp.next print(new_list) def remove(self,key): #鏈表刪除數據函數 if key<0 or key>self.get_length()-1: print("insert error") i=0 temp=self.head while temp !=None: #遍歷找到索引值為 key 的結點 pre=temp temp=temp.next i=i+1 if i==key: pre.next=temp.next temp=None return True pre.next=None def reverse(self): #將鏈表反轉 prev = None current = self.head while current: next_node = current.next current.next = prev prev = current current = next_node self.head = prev
復雜度分析
鏈表屬於常見的一種線性結構,對於插入和移除而言,時間復雜度都為 O(1)
但是對於搜索操作而言,不管從鏈表的頭部還是尾部,都需要遍歷 O(n),所以最好復雜度為 O(1),最壞的情況就是從頭部遍歷到尾部才搜索出對應的元素,所以最壞復雜度為 O(n),平均復雜度為 O(n)。
歸納如下:
- 最好復雜度為 O(1)
- 最壞復雜度為 O(n)
- 平均復雜度為 O(n)