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版的文曲星猜数字游戏代码
Sep 02 Python
编写同时兼容Python2.x与Python3.x版本的代码的几个示例
Mar 30 Python
简单掌握Python中glob模块查找文件路径的用法
Jul 05 Python
Python制作简易注册登录系统
Dec 15 Python
Python把csv数据写入list和字典类型的变量脚本方法
Jun 15 Python
python模糊图片过滤的方法
Dec 14 Python
python opencv实现图像边缘检测
Apr 29 Python
python opencv将图片转为灰度图的方法示例
Jul 31 Python
Django框架HttpResponse对象用法实例分析
Nov 01 Python
flask实现验证码并验证功能
Dec 05 Python
解决pycharm同一目录下无法import其他文件
Feb 12 Python
浅谈Python描述数据结构之KMP篇
Sep 06 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
phpMyAdmin下载、安装和使用入门教程
2007/05/31 PHP
php 无限级分类学习参考之对ecshop无限级分类的解析 带详细注释
2010/03/23 PHP
php实现window平台的checkdnsrr函数
2015/05/27 PHP
PHP运行模式汇总
2016/11/06 PHP
模拟用户操作Input元素,不会触发相应事件
2007/05/11 Javascript
JavaScript 打地鼠游戏代码说明
2010/10/12 Javascript
jquery scrollTop方法根据滚动像素显示隐藏顶部导航条
2013/05/27 Javascript
理解javascript定时器中的setTimeout与setInterval
2016/02/23 Javascript
jQuery控制frames及frame页面JS的方法
2016/03/08 Javascript
使用jQuery实现Web页面换肤功能的要点解析
2016/05/12 Javascript
详解Node.js模块间共享数据库连接的方法
2016/05/24 Javascript
Node.js下自定义错误类型详解
2016/10/17 Javascript
12 款 JS 代码测试必备工具(翻译)
2016/12/13 Javascript
原生JS中slice()方法和splice()区别
2017/03/06 Javascript
详解使用vue-router进行页面切换时滚动条位置与滚动监听事件
2017/03/08 Javascript
Angularjs根据json文件动态生成路由状态的实现方法
2017/04/17 Javascript
Angular 通过注入 $location 获取与修改当前页面URL的实例
2017/05/31 Javascript
详谈JS中数组的迭代方法和归并方法
2017/08/11 Javascript
Vue自定义指令实现checkbox全选功能的方法
2018/02/28 Javascript
基于Vue实现图片在指定区域内移动的思路详解
2018/11/11 Javascript
详解vue 路由跳转四种方式 (带参数)
2019/04/28 Javascript
vue使用swiper.js重叠轮播组建样式
2019/11/14 Javascript
Python Sleep休眠函数使用简单实例
2015/02/02 Python
对Python3 pyc 文件的使用详解
2019/02/16 Python
Python3.6中Twisted模块安装的问题与解决
2019/04/15 Python
一行python实现树形结构的方法
2019/08/09 Python
python 爬取B站原视频的实例代码
2020/09/09 Python
CSS3中新增的对文本和字体的设置
2020/02/03 HTML / CSS
美国最大的宠物用品零售商:PetSmart
2016/11/14 全球购物
Nike荷兰官方网站:Nike.com (NL)
2018/04/19 全球购物
丽笙酒店官方网站:Radisson Hotels
2019/05/07 全球购物
简述数据库的设计过程
2015/06/22 面试题
教师自我评价范文
2013/12/16 职场文书
小学庆六一主持词
2015/06/30 职场文书
MySQL安装后默认自带数据库的作用详解
2021/04/27 MySQL
如何利用Matlab制作一款真正的拼图小游戏
2021/05/11 Python