这个方案里的尾插入,就使用了更高效的prev指标。

但感觉remove的代码不够和前面统一,

我有代码洁癖了????

# coding = utf-8

# 双向链表
class Node:

    # 双向链表存在两个指标,一个向前,一个向后
    def __init__(self, new_data):
        self.data = new_data
        self.prev = None
        self.next = None

    def get_data(self):
        return self.data

    def set_data(self, new_data):
        self.data = new_data

    def get_next(self):
        return self.next

    def set_next(self, new_next):
        self.next = new_next

    def get_prev(self):
        return self.prev

    def set_prev(self, new_prev):
        self.prev = new_prev

class DoubleCycleList:

    def __init__(self):
        self.head = None

    # 作头插入时,需要要注意插入顺序,
    # 总之。要注意不要丢失next和prev。
    def add(self, item):
        node = Node(item)

        # 如果链表是空的,则node的next和prev都指向自己(因为是双向循环)
        if self.is_empty():
            node.set_next(node)
            node.set_prev(node)
            # 将head指向node
            self.head = node
        else:
            # node的next设为现在的head
            node.set_next(self.head)
            # node的prev 设为现在head的prev
            node.set_prev(self.head.get_prev())
            # 现在head的前一个元素的next设为node
            self.head.get_prev().set_next(node)
            # 现在head的前驱 改为node
            self.head.set_prev(node)
            # 将head指向node
            self.head = node

    # 作尾插入
    def append(self, item):
        node = Node(item)
        if self.is_empty():
            # 如果当前链表是空的 那就调用头部插入方法
            self.add(item)
        else:
            # #因为是双向循环链表,所以head的prev其实就是链表的尾部
            # node的下一个设为头
            node.set_next(self.head)
            # node的前驱设为现在头部的前驱
            node.set_prev(self.head.get_prev())
            # 头部前驱的后继设为node
            self.head.get_prev().set_next(node)
            # 头部自己的前驱改为node
            self.head.set_prev(node)

    # 指定位置插入节点
    def insert(self, pos, item):
        # 相当于头插入
        if pos <= 0:
            self.add(item)
        # 相当于尾插入
        elif pos >= self.size():
            self.append(item)
        else:
            node = Node(item)
            count = 0
            current = self.head
            # 在要插入位置的前一个元素,这时候停下
            while count < pos - 1:
                count += 1
                current = current.get_next()
            # node的后继设为cur的后继
            node.set_next(current.get_next())
            # node的前驱设为cur
            node.set_prev(current)
            # cur后继的前驱改为node
            current.get_next().set_prev(node)
            # cur后继改为node
            current.set_next(node)

    # 删除指定节点数据
    def remove(self, item):
        if self.is_empty():
            # 如果链表为空 直接不操作
            return
        else:
            current = self.head
            if current.get_data == item:
                # 如果头结点就是 要删除的元素
                if self.size() == 1:
                    # 如果只有一个节点 链表就空了 head设为None
                    self.head = None
                else:
                    # 头指针指向cur的下一个
                    self.head = current.get_next()
                    # cur后继的前驱改为cur的前驱
                    current.get_next().set_prev(current.get_prev())
                    # cur前驱的后继改为cur的后继
                    current.get_prev().set_next(current.get_next())
            else:
                current = current.get_next()
                # 循环让cur后移一直到链表尾元素位置,期间如果找得到就删除节点,找不到就跳出循环
                while current is not self.head:
                    if current.get_data() == item:
                        # cur的前驱的后继改为cur的后继
                        current.get_prev().set_next(current.get_next())
                        # cur的后继的前驱改为cur的前驱
                        current.get_next().set_prev(current.get_prev())
                    current = current.get_next()

    # 查找指定数据是否存在
    def search(self, item):
        current = self.head
        found = False
        while current is not self.head:
            if current.get_data() == item:
                found = True
            current = current.get_next()
        if current.get_data() == item:
            found = True
        return found

    def is_empty(self):
        return self.head is None

    def __len__(self):
        return self.size()

    def size(self):
        # 循环链表和非循环链表的退出条件不一样
        count = 0
        current = self.head
        while current.get_next() is not self.head:
            count += 1
            current = current.get_next()
        return count

    def show(self):
        current = self.head
        # 循环链表和非循环链表的读取首个元素也不同
        print(current.get_data(), end=' ')
        while current.get_next() is not self.head:
            current = current.get_next()
            print(current.get_data(), end=' ')
        print()

if __name__ == '__main__':
    d_list = DoubleCycleList()
    print(d_list.is_empty())
    d_list.add(5)
    d_list.add(4)
    d_list.add(76)
    d_list.add(23)
    d_list.show()
    d_list.append(48)
    d_list.show()
    d_list.append(234)
    d_list.show()
    d_list.insert(2, 100)
    d_list.show()
    d_list.remove(5)
    d_list.show()
    print(d_list.search(48))
True

False

Process finished with exit code 

python---循环双向链表实现的更多相关文章

  1. Python循环语句

    1.Python循环类型 1.while循环:在某条件下,循环执行某段程序 a. while语句有两个重要命令:continue,break来跳出循环. continue用来跳出该次循环 break用 ...

  2. python 循环语句 函数 模块

    python循环语句 while循环语法结构 当需要语句不断的重复执行时,可以使用while循环 while expression: while_suite 语句ehile_suite会被连续不断的循 ...

  3. jmeter数据库,charles抓包,Python循环语句

    jmeter数据库,charles抓包,Python循环语句 一.Jemeter数据库 添加jar包数据库 jemeter=>浏览 添加JDBC Connection Configuration ...

  4. python循环解压rar文件

    python循环解压rar文件 C:. │ main.py │ ├─1_STL_算法简介 │ STL_算法简介.rar │ └─2_STL_算法_填充新值 STL_算法_填充新值.rar 事情是这样的 ...

  5. python循环语句详细讲解

    想必大家都知道python循环语句吧,可以python循环语句有多种,比如for循环.while循环.if.else等等,   我们可以通过设置条件表达式永远不为 false 来实现无限循环,实例如下 ...

  6. (转)Python 实现双向链表(图解)

    原文:https://blog.csdn.net/qq490691606/article/details/49948263 Python 实现双向链表(图解)双向链表双向链表也叫双链表,是链表的一种, ...

  7. python循环删除列表元素常见错误与正确方法

    python循环删除列表元素 觉得有用的话,欢迎一起讨论相互学习~Follow Me 常见错误 常见错误一:使用固定长度循环删除列表元素 # 使用固定长度循环pop方法删除列表元素 num_list_ ...

  8. Python 循环的技巧

    当在字典中循环时,用 items() 方法可将关键字和对应的值同时取出 >>> knights = {'gallahad': 'the pure', 'robin': 'the br ...

  9. 孤荷凌寒自学python第十五天python循环控制语句

    孤荷凌寒自学python第十五天python循环控制语句 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) python中只有两种循环控制语句 一.while循环 while 条件判断式 1: ...

  10. Python 循环语句(break和continue)

    Python 循环语句(break和continue) while 语句时还有另外两个重要的命令 continue,break 来跳过循环,continue 用于跳过该次循环,break 则是用于退出 ...

随机推荐

  1. Vue CLI 3使用:浏览器兼容性

    package.json 文件里的 browserslist 字段 (或一个单独的 .browserslistrc 文件),指定了项目的目标浏览器的范围.这个值会被 @babel/preset-env ...

  2. VMware Workstation 10序列号:

    VMware Workstation 10序列号:1Y0LW-4WJ9N-LZ5G9-Z81QP-92PN7

  3. 五、Java多人博客系统-2.0版本-数据库设计

    数据库设计表如下:文章类别表.文章表.评论表.留言表. 文章列表表:存放文章类别,首页菜单生成也是从这个表取的. 文章表:存放文章标题.发表时间.内容等信息. 评论表:文章评论内容. 留言表:用户发表 ...

  4. python之property、类方法和静态方法

    一.完整的property1.定义一个方法被伪装成属性之后,应该可以执行一个属性的增删改查操作,增加和修改就对应着被setter装饰的方法,删除一个属性对应着被deleter装饰的方法. @prope ...

  5. 关于申请GMS认证来使用谷歌的一些服务应用及闭源API

    房间内的主要大象正在获取Google移动服务(GMS)的许可证.这是指预先选择的谷歌应用程序阵列,它将谷歌本身的精髓包含在其配置中 -  Google搜索,YouTube,Gmail,Chrome,G ...

  6. 20175221 2018-2019-2 《Java程序设计》第二周学习总结

    20175221   <Java程序设计>第2周学习总结 教材学习内容总结 教材方面 本周学习了第二章的“基本数据类型与数组”的内容,以及粗略地看了一下第三章“运算符.表达式和语句”的内容 ...

  7. Java EE 开发环境搭建

    1 Windows 1.1 JDK 下载: 下载地址:https://developer.oracle.com/java 安装文件:jdk-8u201-windows-x64.exe JDK 并不是越 ...

  8. 使用Redisson实现分布式锁,Spring AOP简化之

    源码 Redisson概述 Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid).它不仅提供了一系列的分布式的Java常用对象,还提供了许多 ...

  9. 10分钟快速搞定pandas

    本文是对pandas官方网站上<10 Minutes to pandas>的一个简单的翻译,原文在这里.这篇文章是对pandas的一个简单的介绍,详细的介绍请参考:Cookbook .习惯 ...

  10. wiki中文语料的word2vec模型构建

    一.利用wiki中文语料进行word2vec模型构建 1)数据获取 到wiki官网下载中文语料,下载完成后会得到命名为zhwiki-latest-pages-articles.xml.bz2的文件,里 ...