双向循环链表的实现

匿名 (未验证) 提交于 2019-12-02 22:56:40
版权声明:本文为博主原创文章,未经博主允许可以转载。 https://blog.csdn.net/killeri/article/details/82864218

其实双向循环链表与单链表的区别在于每个节点的结构发生了改变,具体的说是,每个节点多了一个指针域,用于指向上一个节点。其他的如链表对象就不需要进行改变了。
新的节点类:

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)     

下一章会对链表进行一些总结。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!