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 相关文章推荐
opencv与numpy的图像基本操作
Mar 08 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
Oct 11 Python
Python字典的概念及常见应用实例详解
Oct 30 Python
浅析python redis的连接及相关操作
Nov 07 Python
wxPython窗体拆分布局基础组件
Nov 19 Python
用python中的matplotlib绘制方程图像代码
Nov 21 Python
如何使用Python多线程测试并发漏洞
Dec 18 Python
python标准库os库的函数介绍
Feb 12 Python
python标准库OS模块函数列表与实例全解
Mar 10 Python
用OpenCV进行年龄和性别检测的实现示例
Jan 29 Python
Django使用channels + websocket打造在线聊天室
May 20 Python
python中 Flask Web 表单的使用方法
May 20 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
php file_exists 检查文件或目录是否存在的函数
2010/05/10 PHP
ThinkPHP有变量的where条件分页实例
2014/11/03 PHP
php正则提取html图片(img)src地址与任意属性的方法
2017/02/08 PHP
超简单的jquery的AJAX用法
2010/05/10 Javascript
JS 获取浏览器和屏幕宽高等信息的实现思路及代码
2013/07/31 Javascript
对比分析AngularJS中的$http.post与jQuery.post的区别
2015/02/27 Javascript
深入理解JavaScript系列(17):面向对象编程之概论详细介绍
2015/03/04 Javascript
Bootstrap基础学习
2015/06/16 Javascript
jQuery实现彩带延伸效果的网页加载条loading动画
2015/10/29 Javascript
Boostrap模态窗口的学习小结
2016/03/28 Javascript
微信小程序开发之实现选项卡(窗口顶部TabBar)页面切换
2016/11/25 Javascript
从零开始搭建一个react项目开发
2018/02/09 Javascript
vue实现路由切换改变title功能
2019/05/28 Javascript
JavaScript解析JSON数据示例
2019/07/16 Javascript
jquery实现轮播图特效
2020/04/12 jQuery
在vue中使用console.log无效的解决
2020/08/09 Javascript
微信小程序实现日历签到
2020/09/21 Javascript
[01:57]2018年度DOTA2最具潜力解说-完美盛典
2018/12/16 DOTA
Python的内存泄漏及gc模块的使用分析
2014/07/16 Python
Python编程实现的图片识别功能示例
2017/08/03 Python
Python及PyCharm下载与安装教程
2017/11/18 Python
Python自动化运维之IP地址处理模块详解
2017/12/10 Python
详解Python 数据库的Connection、Cursor两大对象
2018/06/25 Python
使用python代码进行身份证号校验的实现示例
2019/11/21 Python
pytorch 自定义参数不更新方式
2020/01/06 Python
css3 media 响应式布局的简单实例
2016/08/03 HTML / CSS
CSS3 Calc实现滚动条出现页面不跳动问题
2017/09/14 HTML / CSS
夏威夷航空官网:Hawaiian Airlines
2016/09/11 全球购物
美国女孩洋娃娃店:American Girl
2017/10/24 全球购物
Bose英国官方网站:美国知名音响品牌
2020/01/26 全球购物
2014乡镇“三八”国际劳动妇女节活动总结
2014/03/01 职场文书
毕业生见习报告总结
2014/11/08 职场文书
瘦西湖导游词
2015/02/03 职场文书
公司处罚决定书
2015/06/24 职场文书
2015中秋节晚会开场白
2015/07/30 职场文书
2015年中秋放假通知范文
2015/08/18 职场文书