双向链表
一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
双向链表的前四个方法和最后一个方法(__ init__、is_empty、 length 、travel、search)和单链表的一样
代码实现
class Node(object):
def __init__(self, elem):
self.elem = elem
# 后继节点
self.next = None
# 前驱节点
self.prev = None
class DoubleLinkList(object):
def __init__(self):
# 头节点
self.__head = None # 单链表对象的头节点刚开始是指向None的
def is_empty(self):
"""判断链表是否为空"""
return self.__head is None # 如果头节点指向None,那么这个链表就是空链表,直接返回就可以
def length(self):
"""链表长度"""
# cur 游标,用来移动遍历的节点
cur = self.__head
# count 记录节点的数量,有几个节点,链表的长度就是多少
count = 0
while cur is not None:
count += 1
cur = cur.next # 游标向前移动一位,指向下一个节点的地址
return count
def travel(self):
"""遍历整个链表"""
cur = self.__head
while cur is not None:
print(cur.elem, end=' ') # 打印节点存放的数据元素
cur = cur.next
print('')
def add(self, item):
"""链表头部添加元素,头插法 """
node = Node(item)
node.next = self.__head
self.__head = node
node.next.prev = node
def append(self, item):
"""链表尾部添加元素, 尾插法 """
node = Node(item) # 把用户传入的数据存到节点当中
# 先判断一下是不是空链表,因为如果是空链表,是没有下一个节点的,执行 while cur.next is not None:会出错
if self.is_empty():
self.__head = node
else:
cur = self.__head
while cur.next is not None:
cur = cur.next
cur.next = node
node.prev = cur
def insert(self, pos, item):
"""指定位置添加元素"""
# 如果位置<=0,就在头部插入元素
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位置
node = Node(item)
node.next = cur
cur.prev.next = node
node.prev = cur.prev
cur.prev = 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
if cur.next: # 只要cur.next不为空的话就会执行下面的语句
# 判断链表是否只有一个节点,如果只有一个节点,cur.next是没有 prev的
cur.next.prev = None
# 不是头节点
else:
cur.prev.next = cur.next
if cur.next:
cur.next.prev = cur.prev
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
cur = cur.next
return False
if __name__ == "__main__":
dll = DoubleLinkList()
print(dll.is_empty())
print(dll.length())
dll.append(1)
print(dll.is_empty())
print(dll.length())
dll.append(2)
dll.add(8)
dll.append(3)
dll.append(5)
dll.append(4)
dll.append(7)
dll.append(9)
# 8 1 2 3 5 4 7 9
dll.insert(-1, 6)
dll.travel()
dll.insert(3, 100)
dll.travel()
dll.insert(20, 200)
dll.travel()
dll.remove(6)
dll.travel()
dll.remove(100)
dll.travel()
dll.remove(200)
dll.travel()
print(dll.search(8))
print(dll.search(80))