目录
一、双向循环链表
双向循环链表图
二、双向循环链表的操作
1、判断链表是否为空
2,链表长度
3,遍历整个链表
4,在链表头部添加元素
5、链表尾部添加元素
6,在指定位置插入元素
7,修改指定位置的元素
8,删除元素
9、查找元素是否存在
三、完整代码
一、双向循环链表
双向循环链表图
结点node里有三个部分:pre(指向上一结点next的指针)、elem(元素)和next(指向下一结点的指针),head指针指向头结点,尾结点的next指向头结点,头结点的pre指向尾结点的next
二、双向循环链表的操作
1、判断链表是否为空
def is_empty(self):
# 链表是否为空
if self.__head is None:
return True
else:
return False
2,链表长度
def length(self):
# 链表长度
if self.is_empty():
return 0
count = 0
cur = self.__head
while cur.next != self.__head:
count += 1
cur = cur.next
return count
3,遍历整个链表
def travel(self):
# 遍历整个链表
if self.is_empty():
return
cur = self.__head
while cur.next != self.__head:
print(cur.elem, end=' ')
cur = cur.next
print(cur.elem)
4,在链表头部添加元素
def add(self, item):
# 链表头部添加元素
node = Node(item)
if self.is_empty():
# 是空链表头指针直接指向新结点
self.__head = node
# 修改新结点的next指向结点自己
node.next = node
# 新结点的pre指向结点自己的next构成一个结点的双向循环
node.pre = node.next
else:
tail = self.__head
# 循环找到尾结点
while tail.next != self.__head:
tail = tail.next
# 1.新来的节点的next指向第一个头节点
node.next = self.__head
# 2.再改变第一个头节点的指针指向新节点的next
self.__head.pre = node.next
# 3.将尾指向指向添加node节点
tail.next = node
# 4.新结点pre指向尾结点的next
node.pre = tail.next
# 5.最后修改头指针指向新结点
self.__head = node
5、链表尾部添加元素
修改尾结点与新结点的双向指针指向
再修改新结点(这时也是尾结点了)与头结点的双向指针指向
def append(self, item):
# 链表尾部添加元素
# 创建新结点
node = Node(item)
# 是空链表就把头节点指向这个节点
if self.is_empty():
self.__head = node
node.next = node
node.pre = node.next
else:
tail = self.__head
# 找到尾节点
while tail.next != self.__head:
tail = tail.next
# 修改尾结点与新结点的指针
tail.next = node
node.pre = tail.next
# 修改尾结点和头结点的循环指针
node.next = self.__head
self.__head.pre = node.next
6,在指定位置插入元素
找到要插入的位置的前一个结点的指针
修改前一个结点与新插入结点的双向指针
再修改新插入的结点与后一个结点的双向指针
def insert(self, pos, item):
# 位置pos在第一个元素之前,则在头部插入
if pos <= 0:
self.add(item)
# 位置pos大于总长度,则在尾部插入
elif pos > self.length():
self.append(item)
else:
# 指定位置添加元素
node = Node(item)
count = 0
cur = self.__head # 当前指针
# 循环找到要插入的位置的前一个结点指针位置
while count < (pos-1):
count += 1
cur = cur.next
node.next = cur.next
cur.next.pre = node.next
node.pre = cur.next
cur.next = node
7,修改指定位置的元素
def modify(self, pos, item):
"""修改指定位置的元素"""
# 当指定的位置pos小于等于0时,则修改头部元素
if pos <= 0:
self.__head.elem = item
# 当pos大于等于链表总长度时,则修改尾部元素
elif pos >= self.length():
tail = self.__head
# 循环让指针指向尾部元素
while tail.next != self.__head:
tail = tail.next
tail.elem = item # 修改尾部元素
else:
count = 0
tail = self.__head
# 循环指针找到指定的位置
while count < pos: # 1.当不满足条件退出循环时,说明指针已经指向了给定的pos位置
tail = tail.next
count += 1
tail.elem = item # 2.将pos位置的元素修改
8,删除元素
def remove(self, item):
# 删除节点
cur = self.__head # cur当前指针
forword = None # 前一个指针
while cur.next != self.__head:
# 找到了要删除的元素
if cur.elem == item:
# 要删除的元素就是第一个元素
if cur == self.__head:
tail = self.__head
# 让tail指向最后一个元素
while tail.next != self.__head:
tail = tail.next
# 1.尾结点的next指向头结点的next(这个next指向第二个结点)
tail.next = cur.next
# 2.第二个结点的pre指向尾结点的next
cur.next.pre = tail.next
# 3.修改头指针指向第二个结点
self.__head = cur.next
else:
forword.next = cur.next
return
# 未找到要删除的元素,指针向后走,继续遍历
else:
forword = cur
cur = cur.next
# 当上面的while循环不满足条件时(cur.next == self.__head),说明只有一个结点元素
if cur.elem == item:
if cur.next == self.__head:
forword.next = self.__head
9、查找元素是否存在
def search(self, item):
# 查找节点是否存在
cur = self.__head
while cur.next != self.__head:
# 找到了返回True,未回到指向下一个继续遍历
if cur.elem == item:
return True
cur = cur.next
# 查找的元素在最后一个,遍历后指向最后一个,但是没有进入循环,所以需要在循环体外判断一次
if cur.elem == item:
return True
return False
三、完整代码
class Node():
def __init__(self, elem):
# 双向循环链表结点
self.pre = None
self.elem = elem
self.next = None
class DoubleCircleLinkList():
def __init__(self, node=None):
self.__head = node
if node:
node.next = node # 只有一个结点时,next指针指向自己,构成循环
node.pre = node.next
def is_empty(self):
# 链表是否为空
if self.__head is None:
return True
else:
return False
def length(self):
# 链表长度
if self.is_empty():
return 0
count = 0
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
while cur.next != self.__head:
print(cur.elem, end=' ')
cur = cur.next
print(cur.elem)
def add(self, item):
# 链表头部添加元素
node = Node(item)
if self.is_empty():
# 是空链表头指针直接指向新结点
self.__head = node
# 修改新结点的next指向结点自己
node.next = node
# 新结点的pre指向结点自己的next构成一个结点的双向循环
node.pre = node.next
else:
tail = self.__head
# 循环找到尾结点
while tail.next != self.__head:
tail = tail.next
# 1.新来的节点的next指向第一个头节点
node.next = self.__head
# 2.再改变第一个头节点的指针指向新节点的next
self.__head.pre = node.next
# 3.将尾指向指向添加node节点
tail.next = node
# 4.新结点pre指向尾结点的next
node.pre = tail.next
# 5.最后修改头指针指向新结点
self.__head = node
def append(self, item):
# 链表尾部添加元素
# 创建新结点
node = Node(item)
# 是空链表就把头节点指向这个节点
if self.is_empty():
self.__head = node
node.next = node
node.pre = node.next
else:
tail = self.__head
# 找到尾节点
while tail.next != self.__head:
tail = tail.next
# 修改尾结点与新结点的指针
tail.next = node
node.pre = tail.next
# 修改尾结点和头结点的循环指针
node.next = self.__head
self.__head.pre = node.next
def modify(self, pos, item):
"""修改指定位置的元素"""
# 当指定的位置pos小于等于0时,则修改头部元素
if pos <= 0:
self.__head.elem = item
# 当pos大于等于链表总长度时,则修改尾部元素
elif pos >= self.length():
tail = self.__head
# 循环让指针指向尾部元素
while tail.next != self.__head:
tail = tail.next
tail.elem = item # 修改尾部元素
else:
count = 0
tail = self.__head
# 循环指针找到指定的位置
while count < pos: # 1.当不满足条件退出循环时,说明指针已经指向了给定的pos位置
tail = tail.next
count += 1
tail.elem = item # 2.将pos位置的元素修改
def insert(self, pos, item):
# 位置pos在第一个元素之前,则在头部插入
if pos <= 0:
self.add(item)
# 位置pos大于总长度,则在尾部插入
elif pos > self.length():
self.append(item)
else:
# 指定位置添加元素
node = Node(item)
count = 0
cur = self.__head # 当前指针
# 循环找到要插入的位置的前一个结点指针位置
while count < (pos-1):
count += 1
cur = cur.next
node.next = cur.next
cur.next.pre = node.next
node.pre = cur.next
cur.next = node
def remove(self, item):
# 删除节点
cur = self.__head # cur当前指针
forword = None # 前一个指针
while cur.next != self.__head:
# 找到了要删除的元素
if cur.elem == item:
# 要删除的元素就是第一个元素
if cur == self.__head:
tail = self.__head
# 让tail指向最后一个元素
while tail.next != self.__head:
tail = tail.next
# 1.尾结点的next指向头结点的next(这个next指向第二个结点)
tail.next = cur.next
# 2.第二个结点的pre指向尾结点的next
cur.next.pre = tail.next
# 3.修改头指针指向第二个结点
self.__head = cur.next
else:
forword.next = cur.next
return
# 未找到要删除的元素,指针向后走,继续遍历
else:
forword = cur
cur = cur.next
# 当上面的while循环不满足条件时(cur.next == self.__head),说明只有一个结点元素
if cur.elem == item:
if cur.next == self.__head:
forword.next = self.__head
def search(self, item):
# 查找节点是否存在
cur = self.__head
while cur.next != self.__head:
# 找到了返回True,未回到指向下一个继续遍历
if cur.elem == item:
return True
cur = cur.next
# 查找的元素在最后一个,遍历后指向最后一个,但是没有进入循环,所以需要在循环体外判断一次
if cur.elem == item:
return True
return False
if __name__ == '__main__':
ll = DoubleCircleLinkList()
print(ll.is_empty())
print(ll.length())
ll.travel()
print('add')
ll.add(9)
ll.travel()
print('append')
ll.append(13)
ll.travel()
ll.append(14)
ll.travel()
print('insert')
ll.insert(2, 100)
ll.travel()
print('remove')
ll.remove(9)
ll.travel()
print('modify')
ll.modify(1, 200)
ll.travel()
print(ll.search(200))