其实双向循环链表与单链表的区别在于每个节点的结构发生了改变,具体的说是,每个节点多了一个指针域,用于指向上一个节点。其他的如链表对象就不需要进行改变了。
新的节点类:
class LNode:
def __init__(self, elem=0, prev=None, next_=None):
self.prev = prev
self.elem = elem
self.next = next_
实现代码大同小异:
# 节点对象
class LNode:
def __init__(self, elem=0, prev=None, next_=None):
self.prev = prev
self.elem = elem
self.next = next_ # 加个下划线,为了区分python中的next关键字
class listObj:
def __init__(self):
self.rear = None
self.nodenum = 0
# 接下来是一个链表类的实现(意思是:支持链表的一些特定的操作)
class LinkedListUndeflow(ValueError):
pass
# 我们要知道,对于双链表的循环结构,我们要做的就是
# 将链表的第一个节点的prev域指向表尾,链表的最后一个域的nex域指向表首
class LList:
# 建立一个空表
def __init__(self):
self.kerear = listObj()
self.head = None
# 初始化一个链表对象,该链表对象存储有链表的节点数和链表第一个节点的引用
# head就是一个链表实例的属性
# 判断链表是不是空,直接判断链表的表头是不是空就行了
def isEmpty(self):
return self.head is None
# 接下来就是对元素的添加
def prepend(self, elem): # 表头插入
if not self.head:
self.head = LNode(elem, self.kerear.rear, self.head)
self.kerear.rear = self.head
# 建立一个循环,
else:
self.head = LNode(elem, self.kerear.rear, self.head)
self.kerear.nodenum += 1
def append(self, elem):
if not self.head:
self.head = LNode(elem, self.kerear.rear, self.head)
self.kerear.rear = self.head
else:
self.kerear.rear.next = LNode(elem, self.kerear.rear, self.head)
self.kerear.rear = self.kerear.rear.next
self.kerear.nodenum += 1
def popfirst(self): # 表头删除,要求返回删除元素
if not self.head:
raise LinkedListUndeflow("空表不可删除")
e = self.head.elem
self.head.next.prev = self.kerear.rear
self.head = self.head.next
self.kerear.nodenum -= 1
return e
def poplast(self): # 表尾删除
if not self.head:
raise LinkedListUndeflow("空表不可删除")
if not self.head.next:
e = self.head.elem
self.head = self.kerear.rear
self.kerear.nodenum = 0
return e
# 如果是有两个及以上的元素,那么将倒数第二个元素的next指向None就可以了
# 所以要紧的是找到倒数第二个元素
e = self.kerear.rear.elem
self.kerear.rear.prev.next = self.head
self.kerear.rear = self.kerear.rear.prev
self.kerear.nodenum -= 1
return e
def printall(self):
# 这个遍历从头开始遍历的
# 是一个空链表,一个元素的链表,多个元素的链表
p = self.head
while p:
print(p.elem, end = '')
print(',', end = '')
if p.next == self.head:
break
p = p.next
print("\n")
#
# def element(self):
# p = self.kerear.head
# while p:
# yield p.elem
# p = p.next
# # 利用生成器函数,生成一个迭代器(python中进行便利的工具)
mlist1 = LList() # 一个空的链表对象
print(mlist1.isEmpty())
for i in range(10):
# 从首部加入是个元素
mlist1.prepend(i)
print(mlist1.kerear.nodenum, "节点数", sep='--')
mlist1.printall()
# 看看首部加入是否成功
for i in range(10, 20):
mlist1.append(i)
print(mlist1.kerear.nodenum, "节点数", sep='--')
mlist1.printall()
# 看看尾部加入是否成功
print(mlist1.popfirst(),"首部删除返回的", sep = '--')
print(mlist1.kerear.nodenum, "节点数", sep='--')
mlist1.printall()
# 看看首部删除是否成功
print(mlist1.poplast(), "尾部删除节点", sep='--')
print(mlist1.kerear.nodenum, "节点数", sep='--')
mlist1.printall()
# 看看尾部删除是否成功
# for i in mlist1.element():
# print(i)
下一章会对链表进行一些总结。