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使用PyFetion来发送短信的例子
Apr 22 Python
Python中类的继承代码实例
Oct 28 Python
Python中分数的相关使用教程
Mar 30 Python
Python正则抓取网易新闻的方法示例
Apr 21 Python
Python自动化运维_文件内容差异对比分析
Dec 13 Python
Python使用pyautogui模块实现自动化鼠标和键盘操作示例
Sep 04 Python
解决项目pycharm能运行,在终端却无法运行的问题
Jan 19 Python
python和c语言的主要区别总结
Jul 07 Python
利用python在大量数据文件下删除某一行的例子
Aug 21 Python
python hash每次调用结果不同的原因
Nov 21 Python
Python交互环境下打印和输入函数的实例内容
Feb 16 Python
Python中的With语句的使用及原理
Jul 29 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文件上传类分享
2014/11/18 PHP
THINKPHP项目开发中的日志记录实例分析
2014/12/01 PHP
php定义参数数量可变的函数用法实例
2015/03/16 PHP
静态html文件执行php语句的方法(推荐)
2016/11/21 PHP
PHP实现时间比较和时间差计算的方法示例
2017/07/24 PHP
PHP/ThinkPHP实现批量打包下载文件的方法示例
2017/07/31 PHP
php的无刷新操作实现方法分析
2020/02/28 PHP
Javascript this指针
2009/07/30 Javascript
javascript快速排序算法详解
2014/09/17 Javascript
jquery控制背景音乐开关与自动播放提示音的方法
2015/02/06 Javascript
详解javascript实现自定义事件
2016/01/19 Javascript
关于网页中的无缝滚动的js代码
2016/06/09 Javascript
jQuery获取浏览器类型和版本号的方法
2016/07/05 Javascript
jquery插件treegrid树状表格的使用方法详解(.Net平台)
2017/01/03 Javascript
对vue事件的延迟执行实例讲解
2018/08/28 Javascript
jQuery基于随机数解决中午吃什么去哪吃问题示例
2018/12/29 jQuery
发布一款npm包帮助理解npm的使用
2019/01/03 Javascript
jQuery子选择器与可见性选择器实例分析
2019/06/28 jQuery
turn.js异步加载实现翻书效果
2019/07/25 Javascript
Vue的Options用法说明
2020/08/14 Javascript
基于vue中的scoped坑点解说
2020/09/04 Javascript
Python的Flask框架中集成CKeditor富文本编辑器的教程
2016/06/13 Python
python3中set(集合)的语法总结分享
2017/03/24 Python
python编写暴力破解zip文档程序的实例讲解
2018/04/24 Python
Appium+python自动化怎么查看程序所占端口号和IP
2019/06/14 Python
Python中判断子串存在的性能比较及分析总结
2019/06/23 Python
Python flask框架post接口调用示例
2019/07/03 Python
浅析Django 接收所有文件,前端展示文件(包括视频,文件,图片)ajax请求
2020/03/09 Python
call在Python中改进数列的实例讲解
2020/12/09 Python
韩国CJ食品专卖网:CJonmart
2016/09/11 全球购物
年终总结会主持词
2014/03/25 职场文书
我的理想演讲稿
2014/04/30 职场文书
证券区域经理岗位职责
2015/04/10 职场文书
学生病假条怎么写
2015/08/17 职场文书
个人的事迹材料怎么写
2019/04/24 职场文书
2019年特色火锅店的创业计划书模板
2019/08/28 职场文书