Python链表之双向链表
一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
class Node(object): """双向链表节点""" def __init__(self, item): self.elem = item self.next = None self.prev = None class DoubleLinkList(object): """双链表""" def __init__(self): # 初始化一个空链表,变量_head指向None self._head = None def is_empty(self): # 和单链表一样 """判断链表是否为空""" return self._head is None def length(self): # 和单链表一样 """链表长度""" cur = self._head count = 0 while cur is not None: count += 1 cur = cur.next return count def travel(self): # 和单链表一样 """遍历链表""" cur = self._head if self.is_empty(): print("链表为空") else: while cur is not None: print(cur.elem, end=" ") cur = cur.next print("") 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正好指向尾节点 cur = self._head while cur.next is not None: cur = cur.next # 将尾节点cur的next指向node cur.next = node # 将node的prev指向cur node.prev = cur def insert(self, pos, item): """指定位置添加元素 :param pos:从0开始 :param item:需要插入的元素 """ if pos <= 0: self.add(item) elif pos > self.length() - 1: self.append(item) else: count = 0 cur = self._head # 移动到指定位置 while count < pos: count += 1 cur = cur.next # 跳出循环时cur指向指定位置pos:2 node = Node(item) # 将node的next指向cur node.next = cur # 将node的prev指向cur的prev,即位置2 node.prev = cur.prev # 将位置1的next指向node cur.prev.next = node # 将cur的prev指向node cur.prev = node """ # 移动到指定位置的前一个位置 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 while cur is not None: # 进入循环表示链不为空 if cur.elem == item: # 找到该元素 if cur == self._head: # 判断此节点是否是头节点 self._head = cur.next # _head直接就指向cur的下一个节点 if cur.next: # 如果cur的下一个节点不为None,即链表不止一个元素,则让cur下一个节点的prev指向None cur.next.prev = None else: # 如果cur不是头节点 cur.prev.next = cur.next # cur的前一个节点指向cur的后一个节点 if cur.next: # 如果cur的下一个节点不为None cur.next.prev = cur.prev # 则cur后一个节点的prev指向cur的前一个节点 break else: cur = cur.next def search(self, item): # 和单链表一样 """链表查找节点是否存在,并返回True或者False""" cur = self._head while cur is not None: if cur.elem == item: return True else: cur = cur.next return False if __name__ == "__main__": ll = DoubleLinkList() ll.add(1) ll.add(2) ll.append(3) ll.insert(2, 4) ll.insert(4, 5) ll.insert(0, 6) print(ll.length()) ll.travel() print(ll.length()) print(ll.search(3)) print(ll.length()) print(ll.search(4)) ll.remove(1) print(ll.length()) ll.travel()