單向鏈表也叫單鏈表,是鏈表中最簡單的一種形式,它的每一個節點包含兩個域,一個信息域(元素域)和一個連接域。這個連接指向鏈表中的下一個節點,而最後一個節點的連接域則指向一個空值。node
實現python
# 節點實現 class Node(): def __init__(self, item): self.item = item self.next = None # 單鏈表 class SingleLinkList(): def __init__(self): self._head = None def is_empty(self): """判斷鏈表是否爲空""" return self._head == None def length(self): """鏈表長度""" # cur初始時指向頭節點 cur = self._head count = 0 # 尾節點指向None,當未到達尾部時 while cur != None: count += 1 # 將cur後移一個節點 cur = cur.next return count def travel(self): """遍歷鏈表""" cur = self._head while cur != None: print (cur.item, end=' ') cur = cur.next def add(self, item): """頭部添加元素""" # 先建立一個保存item值的節點 node = Node(item) # 將新節點的連接域next指向頭節點,即_head指向的位置 node.next = self._head # 將鏈表的頭_head指向新節點 self._head = node def append(self, item): """尾部添加元素""" node = Node(item) # 先判斷鏈表是否爲空,如果空鏈表,則將_head指向新節點 if self.is_empty(): self._head = node # 若不爲空,則找到尾部,將尾節點的next指向新節點 else: cur = self._head while cur.next != None: cur = cur.next cur.next = node def insert(self, pos, item): """指定位置添加元素""" # 若指定位置pos爲第一個元素以前,則執行頭部插入 if pos <= 0: self.add(item) # 若指定位置超過鏈表尾部,則執行尾部插入 elif pos > (self.length() - 1): self.append(item) # 找到指定位置 else: node = Node(item) count = 0 # pre用來指向指定位置pos的前一個位置pos-1,初始從頭節點開始移動到指定位置 pre = self._head while count < (pos - 1): count += 1 pre = pre.next # 先將新節點node的next指向插入位置的節點 node.next = pre.next # 將插入位置的前一個節點的next指向新節點 pre.next = node def remove(self, item): """刪除節點""" cur = self._head pre = None while cur != None: # 找到了指定元素 if cur.item == item: # 若是第一個就是刪除的節點 if not pre: # 將頭指針指向頭節點的後一個節點 self._head = cur.next else: # 將刪除位置前一個節點的next指向刪除位置的後一個節點 pre.next = cur.next break else: # 繼續按鏈表後移節點 pre = cur cur = cur.next def search(self, item): """鏈表查找節點是否存在,並返回True或者False""" cur = self._head while cur != None: if cur.item == item: return True cur = cur.next return False
單鏈表的一個變形是單向循環鏈表,鏈表中最後一個節點的下一個域再也不爲無,而是指向鏈表的頭節點。app
class Node(object): """節點""" def __init__(self, item): self.item = item self.next = None class SinCycLinkedlist(object): """單向循環鏈表""" def __init__(self): self._head = None def is_empty(self): """判斷鏈表是否爲空""" return self._head == None def length(self): """返回鏈表的長度""" # 若是鏈表爲空,返回長度0 if self.is_empty(): return 0 count = 1 cur = self._head while cur.next != self._head: count += 1 cur = cur.next return count def travel(self): """遍歷鏈表""" if self.is_empty(): return cur = self._head print (cur.item, end=' ') while cur.next != self._head: cur = cur.next print (cur.item) def add(self, item): """頭部添加節點""" node = Node(item) if self.is_empty(): self._head = node node.next = self._head else: #添加的節點指向_head node.next = self._head # 移到鏈表尾部,將尾部節點的next指向node cur = self._head while cur.next != self._head: cur = cur.next cur.next = node #_head指向添加node的 self._head = node def append(self, item): """尾部添加節點""" node = Node(item) if self.is_empty(): self._head = node node.next = self._head else: # 移到鏈表尾部 cur = self._head while cur.next != self._head: cur = cur.next # 將尾節點指向node cur.next = node # 將node指向頭節點_head node.next = self._head def insert(self, pos, item): """在指定位置添加節點""" if pos <= 0: self.add(item) elif pos > (self.length()-1): self.append(item) else: node = Node(item) cur = self._head count = 0 # 移動到指定位置的前一個位置 while count < (pos-1): count += 1 cur = cur.next node.next = cur.next cur.next = node def remove(self, item): """刪除一個節點""" # 若鏈表爲空,則直接返回 if self.is_empty(): return # 將cur指向頭節點 cur = self._head pre = None # 若頭節點的元素就是要查找的元素item if cur.item == item: # 若是鏈表不止一個節點 if cur.next != self._head: # 先找到尾節點,將尾節點的next指向第二個節點 while cur.next != self._head: cur = cur.next # cur指向了尾節點 cur.next = self._head.next self._head = self._head.next else: # 鏈表只有一個節點 self._head = None else: pre = self._head # 第一個節點不是要刪除的 while cur.next != self._head: # 找到了要刪除的元素 if cur.item == item: # 刪除 pre.next = cur.next return else: pre = cur cur = cur.next # cur 指向尾節點 if cur.item == item: # 尾部刪除 pre.next = cur.next def search(self, item): """查找節點是否存在""" if self.is_empty(): return False cur = self._head if cur.item == item: return True while cur.next != self._head: cur = cur.next if cur.item == item: return True return False
一種更復雜的鏈表是「雙向鏈表」或「雙面鏈表」。每一個節點有兩個連接:一個指向前一個節點,當此節點爲第一個節點時,指向空值;而另外一個指向下一個節點,當此節點爲最後一個節點時,指向空值。spa
class Node(object): """雙向鏈表節點""" def __init__(self, item): self.item = item self.next = None self.prev = None class DLinkList(object): """雙向鏈表""" def __init__(self): self._head = None def is_empty(self): """判斷鏈表是否爲空""" return self._head == None def length(self): """返回鏈表的長度""" cur = self._head count = 0 while cur != None: count += 1 cur = cur.next return count def travel(self): """遍歷鏈表""" cur = self._head while cur != None: print (cur.item, end=' ') cur = cur.next def add(self, item): """頭部插入元素""" node = Node(item) if self.is_empty(): # 若是是空鏈表,將_head指向node self._head = node else: # 將node的next指向_head的頭節點 node.next = self._head # 將_head的頭節點的prev指向node self._head.prev = node # 將_head 指向node self._head = node def append(self, item): """尾部插入元素""" node = Node(item) if self.is_empty(): # 若是是空鏈表,將_head指向node self._head = node else: # 移動到鏈表尾部 cur = self._head while cur.next != None: cur = cur.next # 將尾節點cur的next指向node cur.next = node # 將node的prev指向cur node.prev = cur def search(self, item): """查找元素是否存在""" cur = self._head while cur != None: if cur.item == item: return True cur = cur.next return False def insert(self, pos, item): """在指定位置添加節點""" if pos <= 0: self.add(item) elif pos > (self.length() - 1): self.append(item) else: node = Node(item) cur = self._head count = 0 # 移動到指定位置的前一個位置 while count < (pos - 1): count += 1 cur = cur.next # 將node的prev指向cur node.prev = cur # 將node的next指向cur的下一個節點 node.next = cur.next # 將cur的下一個節點的prev指向node cur.next.prev = node # 將cur的next指向node cur.next = node def remove(self, item): """刪除元素""" cur = self._head if cur.item == item: # 若是首節點的元素便是要刪除的元素 if cur.next == None: # 若是鏈表只有這一個節點 self._head = None else: # 將第二個節點的prev設置爲None cur.next.prev = None # 將_head指向第二個節點 self._head = cur.next return while cur != None: if cur.item == item: # 將cur的前一個節點的next指向cur的後一個節點 cur.prev.next = cur.next # 將cur的後一個節點的prev指向cur的前一個節點 cur.next.prev = cur.prev break cur = cur.next