[本文出自天外歸雲的博客園]
鏈表是由節點構成的,一個指針代表一個方向,如果一個構成鏈表的節點都只包含一個指針,那么這個鏈表就是單向鏈表。
單向鏈表中的節點不光有代表方向的指針變量,也有值變量。所以我們定義鏈表,就是要定義鏈表中的節點,對鏈表的操作最后也就是對節點的操作。
這些包含數據的節點們在一種指定的結構下連接起來,成為了一種數據結構——單向鏈表。以上是我對單向鏈表的理解。
以下是我用python3對單向鏈表這種數據結構的一種實現,其中我用到了生成器來完成逆轉單向鏈表這一操作,非常pythonic啊!代碼如下:
''' Python版單向鏈表-單向鏈表簡稱單鏈表 單鏈表中所包含的基本操作: 初始化 創建 鏈表生成器 打印 顯示調用過程 計算長度 判空 獲取 刪除 插入 修改 追加 逆轉單向鏈表 ''' class Node(object): # 節點初始化 def __init__(self, value, p=None): self.value = value self.next = p class LinkList(object): # 初始化單鏈表 def __init__(self): self.head = None # 創建單鏈表 def create(self, node_value_list): self.head = Node(node_value_list[0]) p = self.head for i in node_value_list[1:]: p.next = Node(i) p = p.next # 生成單鏈表 def generate(self): p = self.head while p != None: yield p.value p = p.next # 打印單鏈表 def print(self): print([i for i in self.generate()]) # 顯示方法調用前后的單鏈表 def show(func): def wrapper(self, *args): print("方法{func_name}執行前".format(func_name=func.__name__)) self.print() print("方法{func_name}執行中".format(func_name=func.__name__)) func(self, *args) print("方法{func_name}執行后".format(func_name=func.__name__)) self.print() return wrapper # 獲取單鏈表的長度 def length(self): p = self.head length = 0 while p != None: length += 1 p = p.next return length # 判斷單鏈表是否為空 def is_null(self): return self.length() == 0 # 獲取單鏈表偏移位元素返回並打印其節點值 # 支持順序索引和逆序索引:0代表索引0位,-1代表倒數第一位,-2代表倒數第二位 # 獲取不存在的位返回None def get(self, offset): p = self.head index = 0 length = self.length() if offset > length - 1: print(None) return None if offset < 0 and offset + length < 0: print(None) return None if offset < 0 and offset + length >= 0: offset = length + offset while index < length - 1 and index < offset: p = p.next index += 1 print("獲取索引{index}位節點-值為{value}".format(index=index, value=p.value)) return p # 刪除單鏈表偏移位元素並打印 # 支持順序索引和逆序索引:0代表索引0位,-1代表倒數第一位,-2代表倒數第二位 # 刪除不存在的位返回None @show def remove(self, offset): p = self.head length = self.length() index = 0 if offset > length - 1: print(None) return None if offset == 0 or offset + length == 0: print("刪除索引{index}位節點-值為{value}".format(index=index, value=self.head.value)) self.head = p.next return None if offset < 0 and length + offset > 0: offset = length + offset while index < length - 1 and index < offset - 1: p = p.next index += 1 print("刪除索引{index}位節點-值為{value}".format(index=index + 1, value=p.next.value)) p.next = p.next.next # 在指定index位插入節點-值為value # 什么是插入——在兩個節點之間加入才叫插入 # 所以在末尾插入的意思就是在索引倒數第二位和倒數第一位之間插入 @show def insert(self, offset, value): length = self.length() # 如果偏移量對應的索引位不在鏈表對應索引位范圍內-返回None if offset > length - 1 or offset + length < 0: return None if offset < 0: offset = offset + length node = Node(value) if offset == 0 or offset + length == 0: p = self.head self.head = node node.next = p else: previous_node = self.get(offset - 1) current_node = self.get(offset) previous_node.next = node node.next = current_node print("在索引{index}位插入節點-值為{value}".format(index=offset, value=value)) # 在鏈表索引末位追加一個節點-值為value @show def append(self, value): last_node = self.get(self.length() - 1) last_node.next = Node(value) # 修改鏈表索引位節點值 @show def modify(self, offset, value): self.get(offset).value = value # 逆向生成單向鏈表 @show def reverse(self): # 將節點生成器轉變為列表並逆序 reverse_list = [i for i in self.generate()][::-1] self.head = Node(reverse_list[0]) p = self.head for i in reverse_list[1:]: p.next = Node(i) p = p.next if __name__ == '__main__': list = [1, 2, 33, 4, 55, 6, 76, 78] # 初始化鏈表 link_list = LinkList() # 創建鏈表 link_list.create(list) # 獲取節點 link_list.get(-1) # 刪除節點 link_list.remove(0) # 插入節點 link_list.insert(-2, 0.2) # 末位追加節點 link_list.append(3) # 修改節點值 link_list.modify(-1, 666) # 逆轉 link_list.reverse()