Python双链表原理与实现方法详解


Posted in Python onFebruary 22, 2020

本文实例讲述了Python双链表原理与实现方法。分享给大家供大家参考,具体如下:

Python实现双链表

文章目录

  • Python实现双链表
    • 单链表与双链表比较
    • 双链表的实现
      • 定义链表节点
      • 初始化双链表
      • 判断链表是否为空
      • 双链表尾部添加元素
      • 双链表头部添加节点:
      • 双链表表头删除
      • 双链表按位置插入
      • 双链表删除指定节点
      • 完整代码

单链表与双链表比较

  • 双链表比单链表多一个前驱指针位置,空间效率不占优势
  • 由于双链表中的节点既可以向前也可以向后,相比单链表在查找方面效率更高(可使用二分法)

双链表的实现

定义链表节点

  • class Node(object):
      def __init__(self, value=None, prev=None, next=None):
        self.value = value	# 节点数据域
        self.prev = prev	# 节点前驱指针
        self.next = next	# 节点后继指针

初始化双链表

  • 在双链表类的构造方法中定义头指针以及链表长度属性

  • class doubleLinked(object):
    
      def __init__(self):
        self.head = Node()	# 头指针节点,用于确定链表第一个节点,不计入链表实际长度
        self.length = 0

判断链表是否为空

  • 通过实例属性self.length是否为0判断链表是否为空

  • # 判断链表是否为空
      def is_Empty(self):
        return self.length == 0

双链表尾部添加元素

  • 根据传入的value值创建node节点对象

  • 判断是否为空,若为空则插入节点的前驱节点为head头指针节点,head头指针指向node

  • 如果链表非空:

    • 通过while循环判断当前节点的后继节点是否为None,找到尾节点
    • 找到尾节点后,将尾节点指向待添加节点,待添加节点前驱节点域指向原伪节点
    • 长度+1
  • # 尾部添加
      def append(self, value):
        node = Node(value)
        if self.length == 0:
          node.prev = self.head
          self.head.next = node
        else:
          curnode = self.head.next
          while curnode.next != None:
            curnode = curnode.next
          curnode.next = node
          node.prev = curnode
        self.length += 1

双链表头部添加节点:

  • 调用类方法is_Empty()判断是否为空,若为空则直接调用append()方法

  • 当链表非空时

    • 首先创建待添加节点对象node
    • 设置中间变量存放原头指针指向的节点
    • 将头指针重新指向待添加节点
    • 新添加节点后驱指针域指向中间变量(即原第一个节点)
    • 中间变量前驱指针域指向新添加节点
    • 链表长度+1
  • # 头部添加
      def add(self, value):
        if self.is_Empty():
          self.append(value)
        node = Node(value)
        curnode = self.head.next
        self.head.next = node
        node.next = curnode
        curnode.prev = node
        self.length += 1

双链表表头删除

  • 老样子,依旧要先判断原链表是否为空,为空的时候返回False

  • 链表不为空时:

    • 将头指针指向的节点存放到中间变量curnode
    • 将头指针指向的节点指向头指针(也就是第一个节点现在变成了头指针)
    • 新头指针指向中间变量的后驱节点
    • 链表长度-1
  • # 删除表头节点
      def remove(self):
        if self.is_Empty():
          return False
        curnode = self.head.next
        self.head = self.head.next
        self.head.next = curnode.next
        self.length -= 1

双链表按位置插入

  • 接收两个位置参数,postion和value

  • 创建待插入节点对象

  • 变量curnode存放当前节点,变量i初始值为2(位置参数<2时,默认插入到第二个位置,>2时,通过while循环找到指定位置节点再进行插入)

  • 找到指定位置后,待插入节点的后驱指针指向当前节点curnode的后继节点,待插入节点的前驱节点为当前节点。

  • 当前节点的原后驱节点的前驱指针域指向待插入节点,当前节点curnode的后驱节点变更为插入节点

  • 链表长度+1

  • # 插入到指定位置
      def insert(self, postion, value):
        node = Node(value)
        curnode = self.head.next
        i = 2
        while i < postion:
          i += 1
          curnode = curnode.next
        node.next = curnode.next
        node.prev = curnode
        curnode.next.prev = node
        curnode.next = node
        self.length += 1

双链表删除指定节点

  • 依旧需要判断是否为空,为空时返回False

  • 链表不为空时:

    • 设置中间变量curnode存放当前节点
    • while循环找到相匹配的值的节点
    • 找到相应节点后,应删除节点的前驱节点的后继节点更改为应删除节点的后继节点;应删除节点的后继节点的前驱更改为应删除节点的前驱;
    • 应删除节点后继指针指向自己
    • 链表长度-1
  • # 删除指定节点
      def delete(self, value):
        if self.is_Empty():
          return False
        curnode = self.head.next
        while curnode.value != value:
          curnode = curnode.next
        curnode.prev.next = curnode.next
        curnode.next.prev = curnode.prev
        curnode.next = curnode
        self.length -= 1

完整代码

class Node(object):
  def __init__(self, value=None, prev=None, next=None):
    self.value = value
    self.prev = prev
    self.next = next


class doubleLinked(object):

  def __init__(self):
    self.head = Node()
    self.length = 0

  def __iter__(self):
    for node in self.iter_node():
      yield node.value

  # 对链表进行可迭代操作
  def iter_node(self):
    curnode = self.head.next
    while curnode.next != None:
      yield curnode
      curnode = curnode.next
    if curnode.next == None:
      yield curnode

  # 判断链表是否为空
  def is_Empty(self):
    return self.length == 0

  # 尾部添加
  def append(self, value):
    node = Node(value)
    if self.length == 0:
      node.prev = self.head
      self.head.next = node
    else:
      curnode = self.head.next
      while curnode.next != None:
        curnode = curnode.next
      curnode.next = node
      node.prev = curnode
    self.length += 1

  # 头部添加
  def add(self, value):
    if self.is_Empty():
      self.append(value)
    node = Node(value)
    curnode = self.head.next
    self.head.next = node
    node.next = curnode
    curnode.prev = node
    self.length += 1

  # 插入到指定位置
  def insert(self, postion, value):
    node = Node(value)
    curnode = self.head.next
    i = 2
    while i < postion:
      i += 1
      curnode = curnode.next
    node.next = curnode.next
    node.prev = curnode
    curnode.next.prev = node
    curnode.next = node
    self.length += 1
  # 删除表头节点
  def remove(self):
    if self.is_Empty():
      return False
    curnode = self.head.next
    self.head = self.head.next
    self.head.next = curnode.next
    self.length -= 1

  # 删除指定节点
  def delete(self, value):
    if self.is_Empty():
      return False
    curnode = self.head.next
    while curnode.value != value:
      curnode = curnode.next
    curnode.prev.next = curnode.next
    curnode.next.prev = curnode.prev
    curnode.next = curnode
    self.length -= 1

# 测试
linkedlist = doubleLinked()
print(linkedlist.is_Empty())
linkedlist.append(1)
linkedlist.append(3)
linkedlist.append(5)
linkedlist.add(4)
linkedlist.add(2)
linkedlist.insert(3,10)
linkedlist.remove()
linkedlist.delete(3)
# 遍历打印
i = 1
for node in linkedlist:
  print("第%d个链表节点的值: %d"%(i, node))
  i += 1

运行结果:

True
第1个链表节点的值: 4
第2个链表节点的值: 10
第3个链表节点的值: 1
第4个链表节点的值: 5

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python MySQLdb Windows下安装教程及问题解决方法
May 09 Python
Python中有趣在__call__函数
Jun 21 Python
Python重新加载模块的实现方法
Oct 16 Python
python之mock模块基本使用方法详解
Jun 27 Python
python turtle 绘制太极图的实例
Dec 18 Python
解决pyqt5异常退出无提示信息的问题
Apr 08 Python
基于CentOS搭建Python Django环境过程解析
Aug 24 Python
python中使用.py配置文件的方法详解
Nov 23 Python
matplotlib bar()实现百分比堆积柱状图
Feb 24 Python
浅谈Python基础之列表那些事儿
May 11 Python
总结几个非常实用的Python库
Jun 26 Python
Python+OpenCV实现在图像上绘制矩形
Mar 21 Python
Python单链表原理与实现方法详解
Feb 22 #Python
python函数enumerate,operator和Counter使用技巧实例小结
Feb 22 #Python
python通过文本在一个图中画多条线的实例
Feb 21 #Python
python使用html2text库实现从HTML转markdown的方法详解
Feb 21 #Python
python-sys.stdout作为默认函数参数的实现
Feb 21 #Python
pycharm运行程序时看不到任何结果显示的解决
Feb 21 #Python
Python 安装 virturalenv 虚拟环境的教程详解
Feb 21 #Python
You might like
Linux下PHP连接Oracle数据库
2014/08/20 PHP
PHP中new static()与new self()的区别异同分析
2014/08/22 PHP
php调用shell的方法
2014/11/05 PHP
php输出金字塔的2种实现方法
2014/12/16 PHP
从刷票了解获得客户端IP的方法
2015/09/21 PHP
PHP预定义变量9大超全局数组用法详解
2016/04/23 PHP
PHP实现图片的等比缩放和Logo水印功能示例
2017/05/04 PHP
Laravel如何创建服务器提供者实例代码
2019/04/15 PHP
PHP 实现缩略图
2021/03/09 PHP
js 实现 input type=&quot;file&quot; 文件上传示例代码
2013/08/07 Javascript
使用js实现一个可编辑的select下拉列表
2014/02/20 Javascript
js中定义一个变量并判断其是否为空的方法
2014/05/13 Javascript
JavaScript让网页出现渐隐渐显背景颜色的方法
2015/04/21 Javascript
JavaScript实现的浮动层框架用法实例分析
2015/10/10 Javascript
JS实现六位字符密码输入器功能
2016/08/19 Javascript
jQuery插件ajaxFileUpload异步上传文件
2016/10/19 Javascript
从零开始学习Node.js系列教程三:图片上传和显示方法示例
2017/04/13 Javascript
史上最全JavaScript常用的简写技巧(推荐)
2017/08/17 Javascript
vue vue-Router默认hash模式修改为history需要做的修改详解
2018/09/13 Javascript
详解Vue中使用插槽(slot)、聚类插槽
2019/04/12 Javascript
微信小程序实现手势滑动卡片效果
2019/08/26 Javascript
50行Python代码实现人脸检测功能
2018/01/23 Python
Python代码实现删除一个list里面重复元素的方法
2019/04/02 Python
如何解决pycharm调试报错的问题
2020/08/06 Python
python如何运行js语句
2020/09/09 Python
HTML5文档结构标签
2017/04/21 HTML / CSS
阿里巴巴国际站:Alibaba.com
2016/07/21 全球购物
师范大学毕业自我鉴定
2013/11/21 职场文书
安全目标责任书
2014/07/22 职场文书
《你在为谁工作》心得体会(共8篇)
2016/01/20 职场文书
Nginx+Tomcat实现负载均衡、动静分离的原理解析
2021/03/31 Servers
PostgreSQL存储过程实用脚本(二):创建函数入门
2021/04/05 PostgreSQL
pandas 实现将NaN转换为None
2021/05/14 Python
python中mongodb包操作数据库
2022/04/19 Python
Android开发手册Chip监听及ChipGroup监听
2022/06/10 Java/Android
nginx配置指令之server_name的具体使用
2022/08/14 Servers