双向链表
- 一种更复杂的链表是”双向链表”或”双面链表”。每个结点有两个链接:一个指向前一个结点,当此结点为第一个结点时,指向空值;而另一个指向下一个结点,当此结点为最后一个结点时,指向空值。
1. 双向链表的操作
• is_empty() 链表是否为空
• length() 链表长度
• travel() 遍历链表
• add(item) 链表头部添加
• append(item) 链表尾部添加
• insert(pos, item) 指定位置添加
• remove(item) 删除节点
• search(item) 查找节点是否存在
2. 双向链表的实现
- 双向链表结点实现
class Node(object):
"""节点类型"""
def __init__(self,item):
# 保存元素
self.item = item
# 保存下一个节点
self.next = None
# 保存上一个节点
self.pre = None
- 双向链表的初始化
class DoubleLinkList(object):
"""链表"""
def __init__(self):
self.__head = None
- 双向链表的判断是否为空、链表的长度、遍历链表
def is_empty(self):
"""链表是否为空"""
# if self.__head is None:
# return True
# return False
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
while cur is not None:
print(cur.item, end=' ')
# 在这个位置 cur 就是上一个节点
cur = cur.next
- 双向链表的头部添加元素
def add(self,item):
"""头部添加元素"""
node = Node(item)
if self.__head is not None:
node.next = self.__head
self.__head.pre = node
# 无论列表是否为空 在头部添加节点的时候 该代码都需要执行
self.__head = node
- 双向链表的尾部添加元素
def append(self,item):
"""链表的尾部追加元素"""
if self.is_empty():
self.add(item)
return
cur = self.__head
# 程序在此处会如果是空链表会boom
while cur.next is not None:
cur = cur.next
# 退出循环之后 cur 指向的就是最后一个节点
# 实例化新节点
node = Node(item)
cur.next = node
node.pre = cur
- 双向链表查找元素是否存在
def search(self,item):
"""查找节点是否存在"""
# 遍历 满足条件就认为找到 return True
cur = self.__head
while cur is not 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:
# 在中间某一个位置添加元素
# 角标为的位置添加元素, 遍历的时候需要获取1位置的前端节点
index = 0
cur = self.__head
while index < pos:
index = index + 1
cur = cur.next
# 循环退出之后 cur 指向的就是前端节点
node = Node(item)
node.next = cur
node.pre = cur.pre
cur.pre.next = node
cur.pre = node
- 删除元素
def remove(self,item):
"""删除元素,只删除第一个元素"""
cur = self.__head
while cur is not None:
# 比较节点的 item 和删除的 item 是否相等
if cur.item == item:
# 如果删除的是首节点
if cur == self.__head:
self.__head = cur.next
if cur.next is not None:
# 链表中只有一个节点的时候
cur.next.pre = None
else:
cur.pre.next = cur.next
# 当删除的是尾节点的时候 cur.next = None
if cur.next is not None:
cur.next.pre = cur.pre
# 只删除一个元素 为 item 的节点
return
cur = cur.next
3. 双向链表的实现(完整功能)
class Node(object):
"""节点类型"""
def __init__(self,item):
# 保存元素
self.item = item
# 保存下一个节点
self.next = None
# 保存上一个节点
self.pre = None
# 以面向对象的方式来操作链表
# 增删改查
class DoubleLinkList(object):
"""链表"""
def __init__(self):
self.__head = None
"""
is_empty() 链表是否为空
length() 链表长度
travel() 遍历整个链表
add(item) 链表头部添加元素
append(item) 链表尾部添加元素
insert(pos, item) 指定位置添加元素
remove(item) 删除节点
search(item) 查找节点是否存在
"""
def is_empty(self):
"""链表是否为空"""
# if self.__head is None:
# return True
# return False
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
while cur is not None:
print(cur.item, end=' ')
# 在这个位置 cur 就是上一个节点
cur = cur.next
def search(self,item):
"""查找节点是否存在"""
# 遍历 满足条件就认为找到 return True
cur = self.__head
while cur is not None:
if cur.item == item:
return True
cur = cur.next
# 默认没有找到
return False
def add(self,item):
"""头部添加元素"""
node = Node(item)
if self.__head is not None:
node.next = self.__head
self.__head.pre = node
# 无论列表是否为空 在头部添加节点的时候 该代码都需要执行
self.__head = node
def append(self,item):
"""链表的尾部追加元素"""
if self.is_empty():
self.add(item)
return
cur = self.__head
# 程序在此处会如果是空链表会boom
while cur.next is not None:
cur = cur.next
# 退出循环之后 cur 指向的就是最后一个节点
# 实例化新节点
node = Node(item)
cur.next = node
node.pre = cur
def insert(self, pos,item):
"""在指定的位置插入元素"""
if pos <= 0:
self.add(item)
elif pos > (self.length() - 1):
self.append(item)
else:
# 在中间某一个位置添加元素
# 角标为的位置添加元素, 遍历的时候需要获取1位置的前端节点
index = 0
cur = self.__head
while index < pos:
index = index + 1
cur = cur.next
# 循环退出之后 cur 指向的就是前端节点
node = Node(item)
node.next = cur
node.pre = cur.pre
cur.pre.next = node
cur.pre = node
def remove(self,item):
"""删除元素,只删除第一个元素"""
cur = self.__head
while cur is not None:
# 比较节点的 item 和删除的 item 是否相等
if cur.item == item:
# 如果删除的是首节点
if cur == self.__head:
self.__head = cur.next
if cur.next is not None:
# 链表中只有一个节点的时候
cur.next.pre = None
else:
cur.pre.next = cur.next
# 当删除的是尾节点的时候 cur.next = None
if cur.next is not None:
cur.next.pre = cur.pre
# 只删除一个元素 为 item 的节点
return
cur = cur.next
if __name__ == '__main__':
single = DoubleLinkList()
print(single.is_empty()) # True
print(single.length()) # 0
single.append(0)
# single.remove(0) # <>
single.add(1)
single.add(2)
print(single.is_empty()) # False
print(single.length()) # 3
single.travel() # 2,1,0
print(" ")
print(single.search(1)) # True
print(single.search(10)) # False
single.append(5)
single.travel() # 2,1,0,5
print(" ")
single.insert(100000,6)
single.insert(-10,8)
single.insert(1,11) # 8,11,2,1,0,5,6
single.travel()
print(" ")
single.remove(0) # 8,11,2,1,5,6
single.travel()
print(" ")
single.remove(8) # 11,2,1,5,6
single.travel()
print(" ")
single.remove(6) # 11,2,1,5
single.travel()