这个和单向链表有几个功能是同样的代码。

但在add,insert,append,remove时,由于node拥有prev指针,

所以操作不一样。注意看注释。

# 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 DoubleList:

    def __init__(self):
        self.head = None

    # 作头插入时,需要要注意插入顺序,
    # 总之。要注意不要丢失next和prev。
    def add(self, item):
        node = Node(item)
        if not self.is_empty():
            # 待插入节点的后继区指向原头节点
            node.set_next(self.head)
            # 原头节点的前驱区指向待插入节点
            self.head.set_prev(node)
        # 将head指向node
        self.head = node

    # 作尾插入时,需要先判断是否为空列表。因为空列表时,没有next。
    # 为空列表时,尾插入和头插入代码相同。
    # 当不为空时,需要循环到底,再作插入处理
    def append(self, item):
        node = Node(item)
        if self.is_empty():
            # 将head指向node
            self.head = node
        else:
            # 移动到链表尾部
            current = self.head
            while current.get_next() is not None:
                current = current.get_next()
            # 将尾节点cur的next指向node
            current.set_next(node)
            # 将node的prev指向cur
            node.set_prev(current)

    # 指定位置插入节点
    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的prev指向cur
            node.set_prev(current)
            # 将node的next指向cur的下一个节点
            node.set_next(current.get_next())
            # 将cur的下一个节点的prev指向node
            current.get_next().set_prev(node)
            # 将cur的next指向node
            current.set_next(node)

    # 删除指定节点数据
    def remove(self, item):
        # 删除时,不需要再使用一个prev变量了。因为双向链表本身有这个指针
        current = self.head
        while current is not None:
            if current.get_data() == item:
                # 在找到节点之后,需要判断是否为首节点
                if current == self.head:
                    self.head = current.get_next()
                    # 判断链表是否只有一个结点
                    if current.get_next():
                        current.get_next().set_prev(None)
                else:
                    current.get_prev().set_next(current.get_next())
                    # 如果存在下一个结点,则设置下一个结点
                    if current.get_next():
                        current.get_next().set_prev(current.get_prev())
                break
            else:
                current = current.get_next()

    # 查找指定数据是否存在
    def search(self, item):
        current = self.head
        found = False
        while current is not None:
            if current.get_data() == item:
                found = True
            current = current.get_next()
        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 is not None:
            count += 1
            current = current.get_next()
        return count

    def show(self):
        current = self.head
        while current is not None:
            print(current.get_data(), end=' ')
            current = current.get_next()
        print('\n')

if __name__ == '__main__':
    d_list = DoubleList()
    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))
C:\Users\Sahara\.virtualenvs\test\Scripts\python.exe C:/Users/Sahara/PycharmProjects/test/python_search.py
True

True

Process finished with exit code 

python---自己实现双向链表常用功能的更多相关文章

  1. Python 基本数据类型_常用功能整理

    一.字符串 字符串 s ="axle" #去两端空格 s.split() #以什么开头 s.startswith("a") #查找子序列,"12&qu ...

  2. 【python】【logging】python日志模块logging常用功能

    logging模块:应用程序的灵活事件日志系统,可以打印并自定义日志内容 logging.getLogger 创建一个log对象 >>> log1=logging.getLogger ...

  3. python中time模块常用功能

    import time time模块提供了大量对时间进行处理的方法 time.time() # 获取当前时间戳,得到自1970年开始的秒数 >>>time.time() 155487 ...

  4. python基本数据类型及常用功能

    1.数字类型 int -int(将字符串转换为数字) a = " print(type(a),a) b = int(a) print(type(b),b) num = " v = ...

  5. Python常用功能函数

    Python常用功能函数汇总 1.按行写字符串到文件中 import sys, os, time, json def saveContext(filename,*name): format = '^' ...

  6. python轻量级orm框架 peewee常用功能速查

    peewee常用功能速查 peewee 简介 Peewee是一种简单而小的ORM.它有很少的(但富有表现力的)概念,使它易于学习和直观的使用. 常见orm数据库框架 Django ORM peewee ...

  7. Python常用功能函数总结系列

    Python常用功能函数系列总结(一) 常用函数一:获取指定文件夹内所有文件 常用函数二:文件合并 常用函数三:将文件按时间划分 常用函数四:数据去重 Python常用功能函数系列总结(二) 常用函数 ...

  8. Python OS模块常用功能 中文图文详解

    一.Python OS模块介绍 OS模块简单的来说它是一个Python的系统编程的操作模块,可以处理文件和目录这些我们日常手动需要做的操作. 可以查看OS模块的帮助文档: >>> i ...

  9. python爬虫:一些常用的爬虫技巧

    python爬虫:一些常用的爬虫技巧 1.基本抓取网页 get方法: post方法: 2.使用代理IP 在开发爬虫过程中经常会遇到IP被封掉的情况,这时就需要用到代理IP; 在urllib2包中有Pr ...

随机推荐

  1. mysql-python安装时EnvironmentError: mysql_config not found

    mysql-python安装时EnvironmentError: mysql_config not found 在安装 mysql-python时,会出现: 复制代码 sh: mysql_config ...

  2. FastStone Capture激活码

    用户名:c1ikm注册码:AXMQX-RMMMJ-DBHHF-WIHTV 或 AXOQS-RRMGS-ODAQO-APHUU

  3. Django+Vue打造购物网站(四)

    首页商品类别数据显示 商品分类接口 大概需要两个,一个显示三个类别 一个显示类别及类别下的全部商品 现在开始写商品的接口 首先编写三个分类的serializer class CategorySeria ...

  4. codeforces选做

    收录了最近本人完成的一部分codeforces习题,不定期更新 codeforces 1132E Knapsack 注意到如果只使用某一种物品,那么这八种物品可以达到的最小相同重量为\(840\) 故 ...

  5. 利用 Python_tkinter 完成 2048 游戏

    成品展示 具备基本的数据合并以及分数统计,不同数字的色块不同 产生随机数, 数据无法合并判定以及重新开始选项 同时可以判定游戏失败条件 需求分析 完成基本数据合并算法 游戏结束条件 界面展示 重置按钮 ...

  6. macOS 上编译 Dynamips

    Dynamips 是一个Cisco 路由器模拟软件. 安装过程: git clone git://github.com/GNS3/dynamips.git cd dynamips mkdir buil ...

  7. UOJ#310.【UNR #2】黎明前的巧克力(FWT)

    题意 给出 \(n\) 个数 \(\{a_1, \cdots, a_n\}\),从中选出两个互不相交的集合(不能都为空),使得第一个集合与第二个集合内的数的异或和相等,求总方案数 \(\bmod 99 ...

  8. python 发送post和get请求

    摘自:http://blog.163.com/xychenbaihu@yeah/blog/static/132229655201231085444250/ 测试用CGI,名字为test.py,放在ap ...

  9. A Reliability-Aware Network Service Chain Provisioning With Delay Guarantees in NFV-Enabled Enterprise Datacenter Networks

    文章名称:A Reliability-Aware Network Service Chain Provisioning With Delay Guarantees in NFV-Enabled Ent ...

  10. 纯js Ajax 请求

    var XMLHttpReq; function createXMLHttpRequest() { if(window.ActiveXObject ) { try { XMLHttpReq = new ...