双向链表
每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
代码实现:
class Node:
"""双向链表节点"""
def __init__(self, item):
self.item = item
self.next = None
self.pre = None
class DoubleLinkList:
"""双向链表"""
def __init__(self):
self.__head = None
def __str__(self):
"""打印链表对象"""
str1 = "["
cur = self.__head
while cur is not None:
str1 += str(cur.item)
str1 += ", "
cur = cur.next
str1 += "]"
return str1
def is_empty(self):
"""判断链表是否为空
:return 如果链表为空 返回真
"""
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 search(self, item):
"""查找元素是否存在"""
cur = self.__head
while cur is not None:
if cur.item == item:
return True
cur = cur.next
return False
def add(self, item):
"""头部插入元素
:param item:要保存的具体数据
"""
node = Node(item)
node.next = self.__head
self.__head = node
if node.next:
node.next.pre = node
def append(self, item):
"""尾部插入元素"""
node = Node(item)
if self.is_empty():
# 如果是空链表,将__head指向node
self.__head = node
else:
# 移动到链表尾部
cur = self.__head
while cur.next is not None:
cur = cur.next
# 将node的pre指向cur
node.pre = cur
# 将尾节点cur的next指向node
cur.next = node
def insert(self, pos, item):
"""在指定位置添加节点"""
if pos <= 0:
self.add(item)
elif pos >= self.length():
self.append(item)
else:
cur = self.__head
count = 0
# 移动到指定位置的前一个位置
while count <= pos:
count += 1
cur = cur.next
# 将node的pre指向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:
# 找到了要删除的元素
if cur.item == item:
# 先判断此结点是否是头节点
# 头节点
if cur == self.__head:
self.__head = cur.next
# 如果存在下一个节点,则设置下一个节点
if cur.next:
# 判断链表是否只有一个节点
self.__head.pre = None
else:
cur.pre.next = cur.next
# 如果存在下一个节点,则设置下一个节点
if cur.next:
cur.next.pre = cur.pre
return
# 不是要找的元素 移动游标
cur = cur.next
if __name__ == '__main__':
sll = DoubleLinkList()
# 打印链表的长度
print("链表的长度", end=" ")
print(sll.length())
# 打印链表
print(sll)
# 向链表追加节点
sll.append(1)
# 向链表添加节点
sll.add(2)
# 向链表插入节点
sll.insert(0, 3)
# 打印链表
print(sll)
# 判断链表是否为空
print("链表是否为空", end=" ")
print(sll.is_empty())
# 判断节点是否存在
print("判断节点3是否存在", end=" ")
print(sll.search(3))
# 删除节点
sll.remove(3)
# 打印链表
print(sll)
单向循环链表
单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点。
单向循环链表的实现
class Node:
"""单链表的节点"""
def __init__(self, item):
# item存放数据元素
self.item = item
# next是下一个节点的标识
self.next = None
class CycleSingleLinkList:
"""单向循环链表"""
def __init__(self, node=None):
# 头节点指向第一个节点
self.__head = node
def __str__(self):
"""遍历列表"""
if self.is_empty():
return "[ ]"
sll = "["
cur = self.__head
while cur.next != self.__head:
sll += str(cur.item)
sll += ", "
cur = cur.next
sll += str(cur.item)
sll += "]"
return sll
def is_empty(self):
"""判断链表是否为空"""
return self.__head is None
def length(self):
"""链表长度"""
if self.is_empty():
return 0
# cur初始时指向头节点
cur = self.__head
count = 1
# 尾节点指向None,当未达到尾部时
while cur.next != self.__head:
count += 1
# 将cur后移一个节点
cur = cur.next
return count
def add(self, item):
"""
链表头部添加元素
:param item: 要保存的数据
"""
node = Node(item)
if self.is_empty():
self.__head = node
node.next = node
# 寻找尾节点
cur = self.__head
while cur.next != self.__head:
cur = cur.next
# 从循环退出,cur指向的尾节点
node.next = self.__head
self.__head = node
cur.next = self.__head
def append(self, item):
"""列表尾部添加元素"""
node = Node(item)
if self.is_empty():
# 如果链表为空的话,则直接把新节点放在头部
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head:
cur = cur.next
# 退出循环的时候,cur指向尾节点
cur.next = node
node.next = self.__head
def insert(self, pos, item):
"""指定位置添加元素"""
# 在头部添加元素
if pos <= 0:
self.add(item)
# 若指定位置超过链表尾部,则执行尾部插入
elif pos >= self.length():
self.append(item)
# 找到指定位置
else:
cur = self.__head
count = 0
while count < (pos-1):
count += 1
# 退出循环时,cur指向pos的前一个位置
cur = cur.next
node = Node(item)
node.next = cur.next
cur.next = node
def remove(self, item):
"""删除节点"""
if self.is_empty():
return
cur = self.__head
pre = None
while cur.next != self.__head:
# 找到了要删除的元素
if cur.item == item:
# 在头部找到了元素
if cur == self.__head:
# 先找到尾节点
rear = self.__head
while rear.next != self.__head:
rear = rear.next
# 退出循环后,rear指向为尾节点
self.__head = cur.next
rear.next = self.__head
else:
pre.next = cur.next
return
# 不是要找的元素 移动游标
pre = cur
cur = cur.next
# 退出循环后 cur指向尾节点
if cur.item == item:
# 链表只有一个节点
if cur == self.__head:
self.__head = Node
else:
pre.next = self.__head
def search(self, item):
"""查找节点是否存在"""
if self.is_empty():
return False
cur = self.__head
while cur.next != self.__head:
if cur.item == item:
return True
cur = cur.next
# 退出循环后 cur指向尾节点
if cur.item == item:
return True
return False
if __name__ == '__main__':
# 生成链表对象
sll = CycleSingleLinkList()
# 打印链表的长度
print("链表的长度", end=" ")
print(sll.length())
# 打印链表
print(sll)
# 向链表追加节点
sll.append(1)
# 向链表添加节点
sll.add(2)
# 向链表插入节点
sll.insert(0, 3)
# 打印链表
print(sll)
# 判断链表是否为空
print("链表是否为空", end=" ")
print(sll.is_empty())
# 判断节点是否存在
print("判断节点3是否存在", end=" ")
print(sll.search(3))
# 删除节点
sll.remove(3)
# 打印链表
print(sll)
exit(?)