python实现单链表的方法示例


Posted in Python onSeptember 03, 2019

前言

首先说下线性表,线性表是一种最基本,最简单的数据结构,通俗点讲就是一维的存储数据的结构。

线性表分为顺序表和链接表:

  • 顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,称为线性表的顺序存储结构或顺序映像;
  • 链式表示指的是用一组任意的存储单元存储线性表中的数据元素,称为线性表的链式存储结构。而他既可以是连续的也可以不连续,是通过一个与后继结点的连接信息构建起来的。

*顺序表(这个不是本次重点,简单介绍一下)

顺序表是用一段连续的存储单元依次存储数据元素,查找元素是很方便的,但是如果要向其中添加删除元素就不那么简单了。因为添加删除元素要先找到那个位置,由于顺序表内部是通过地址的连续才使他成为一个表,当删掉元素时,要把后面的元素全部向前移,填补上空出来的地址空间;添加元素也是一样,需要先把该位置后面的元素向后移去,才能在这块地址上添加元素。

以C语言为例:顺序表可以通过一个数组来表示,每创建一个数组就对应给他分配一块内存。当然除了静态分配空间,还可以动态扩展。后续的操作要在这块内存上进行,一般都需要移动数组元素,复杂度会很高。

在python中,顺序表还有两种表示方式:

  • 一体式结构
  • 分离式结构

这里的一体和分离是指表中的元素集合,和为实现正确操作而需记录的信息,这两部分是在同一块空间还是在旁边的一块新的空间中。

python中的tuple和list就是采用了顺序表的实现技术,不过tuple是不可变的,不支持对内部的操作。而list是一个元素个数可变的线性表,支持添加删除等操作。list的思想其实是和C语言中一样的,只是对其中的功能进行了一些封装,也就是list的那些属性。

*链式表

链表,顾名思义,相邻结点是通过链来连接的,那么什么是链呢。我们知道,C语言中有指针,指针通过地址来找到他的目标。如此说来,一个节点不仅仅有他的元素,还需要有一个他下一个元素的地址。

python实现单链表的方法示例

那么,这里需要指针和地址。python中的指针是什么呢?下面先把这个放一下,先去理解一下python里面变量标识的实质。

python实现单链表的方法示例

先看一下这个,为什么a和b的id是一样的呢?那我再问一个问题:python中交换两个变量的值时怎样来实现的?

1 a = 10
2 b = 20
3 a,b = b,a

为什么python可以这样来赋值呢?下面我再画一幅图。

python实现单链表的方法示例 python实现单链表的方法示例

现在是否能理解了呢,变量本身就是存储的一个地址,交换他们的值就是把自己的指向更改一下。那么现在知道了标识的含义,我们的指针域该怎么写呢,是不是直接用变量等于下一个结点啊。这样看来就不复杂了,接下来的内容就和一般的链表一样了。我在这里说这些就是为了弄清楚python是怎么建立链接的。

一、单链表

那么下面就通过一个类来实现一个节点,节点当中包括数据域和链接域,代码中实现了一些常用的功能,比如插入,查找等等。今天主要是说一下单链表是如何运用到python中的,由于我之前没有了解过这些。学习了之后,用自己之前的知识,就可以很方便的运用链表了。后面的代码就不过多解释了,自己仔细琢磨一下。有什么不理解的可以留言,我会尽量详细的回复。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date  : 2018-06-12 11:23:21
# @Author : yudanqu (943775910@qq.com)
# @Link  : https://www.cnblogs.com/yudanqu/
# @Version : $Id$


class Node(object):
  """节点"""

  def __init__(self, elem):
    self.elem = elem
    self.next = None # 初始设置下一节点为空

'''
上面定义了一个节点的类,当然也可以直接使用python的一些结构。比如通过元组(elem, None)
'''


# 下面创建单链表,并实现其应有的功能


class SingleLinkList(object):
  """单链表"""

  def __init__(self, node=None): # 使用一个默认参数,在传入头结点时则接收,在没有传入时,就默认头结点为空
    self.__head = node

  def is_empty(self):
    '''链表是否为空'''
    return self.__head == None

  def length(self):
    '''链表长度'''
    # cur游标,用来移动遍历节点
    cur = self.__head
    # count记录数量
    count = 0
    while cur != None:
      count += 1
      cur = cur.next
    return count

  def travel(self):
    '''遍历整个列表'''
    cur = self.__head
    while cur != None:
      print(cur.elem, end=' ')
      cur = cur.next
    print("\n")

  def add(self, item):
    '''链表头部添加元素'''
    node = Node(item)
    node.next = self.__head
    self.__head = node

  def append(self, item):
    '''链表尾部添加元素'''
    node = Node(item)
    # 由于特殊情况当链表为空时没有next,所以在前面要做个判断
    if self.is_empty():
      self.__head = node
    else:
      cur = self.__head
      while cur.next != None:
        cur = cur.next
      cur.next = node

  def insert(self, pos, item):
    '''指定位置添加元素'''
    if pos <= 0:
        # 如果pos位置在0或者以前,那么都当做头插法来做
      self.add(item)
    elif pos > self.length() - 1:
      # 如果pos位置比原链表长,那么都当做尾插法来做
      self.append(item)
    else:
      per = self.__head
      count = 0
      while count < pos - 1:
        count += 1
        per = per.next
      # 当循环退出后,pre指向pos-1位置
      node = Node(item)
      node.next = per.next
      per.next = node

  def remove(self, item):
    '''删除节点'''
    cur = self.__head
    pre = None
    while cur != None:
      if cur.elem == item:
        # 先判断该节点是否是头结点
        if cur == self.__head:
          self.__head = cur.next
        else:
          pre.next = cur.next
        break
      else:
        pre = cur
        cur = cur.next

  def search(self, item):
    '''查找节点是否存在'''
    cur = self.__head
    while not cur:
      if cur.elem == item:
        return True
      else:
        cur = cur.next
    return False


if __name__ == "__main__":

    # node = Node(100) # 先创建一个节点传进去

  ll = SingleLinkList()
  print(ll.is_empty())
  print(ll.length())

  ll.append(3)
  ll.add(999)
  ll.insert(-3, 110)
  ll.insert(99, 111)
  print(ll.is_empty())
  print(ll.length())
  ll.travel()
  ll.remove(111)
  ll.travel()

二、单向循环链表和双向链表

与单链表相关联的,还有单向循环链表和双向链表:

单向循环链表:在单链表的基础上,再多一个由尾节点指向首节点的链接,首节点是指链表的第一个存数据的结点,而头结点是指指向第一个存数据的结点的那个东西,仅有个链接域,而不是真正存储内容的链表结点。需要注意的是,循环链表中,一些功能的创建是和单链表不一样的,比如判空、判满,它是循环的该怎么判断呢?这些内容可以在上面给出的单链表的实现中进行修改获得,可以试一下。

双向链表:与单链表相比,这个新增的特性就是双向。可以从前面向后面传递,也可以从后面向前面传递,这个前面和后面是我们自己定义的,认为从一端到另一端是正向,那么倒过来则相反。这个双向链表的实现和单链表也是基本上一样的。单向链表是除了数据域再添加一个链接域,来指向下一个结点。那么同样的道理,双向链表就再添加一个指向前一个结点的链接不就好了。这个时候再创建链表的时候就要把每个节点与前驱结点以及后继结点的链接建立好。

python实现单链表的方法示例

双向链表的插入和删除等等操作,都要注意,不要把存储的地址信息丢了,仔细考虑好两边的指向,先把谁链接上去,再链接谁。

python实现单链表的方法示例

今天本来只想说说前面那一点点内容的,写的写的,后面感觉不得不说一下,不过也没有写的比较完整。大家捡有用的东西来看。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python连接mongodb操作数据示例(mongodb数据库配置类)
Dec 31 Python
Python标准库之多进程(multiprocessing包)介绍
Nov 25 Python
Python正则替换字符串函数re.sub用法示例
Jan 19 Python
Python读写/追加excel文件Demo分享
May 03 Python
Python实现多条件筛选目标数据功能【测试可用】
Jun 13 Python
python中metaclass原理与用法详解
Jun 25 Python
Python利用scapy实现ARP欺骗的方法
Jul 23 Python
python3 深浅copy对比详解
Aug 12 Python
python3+opencv生成不规则黑白mask实例
Feb 19 Python
Django权限设置及验证方式
May 13 Python
如何基于Python pygame实现动画跑马灯
Nov 18 Python
python 三种方法提取pdf中的图片
Feb 07 Python
python中enumerate() 与zip()函数的使用比较实例分析
Sep 03 #Python
python网络编程之多线程同时接受和发送
Sep 03 #Python
springboot配置文件抽离 git管理统 配置中心详解
Sep 02 #Python
python生成随机红包的实例写法
Sep 02 #Python
Django发送邮件功能实例详解
Sep 02 #Python
python读取Excel表格文件的方法
Sep 02 #Python
python将字典列表导出为Excel文件的方法
Sep 02 #Python
You might like
php生成缩略图填充白边(等比缩略图方案)
2013/12/25 PHP
PHP中substr函数字符串截取用法分析
2016/01/07 PHP
PHP实现APP微信支付的实例讲解
2018/02/10 PHP
Jquery 获取表单text,areatext,radio,checkbox,select值的代码
2009/11/12 Javascript
比Jquery的document.ready更快的方法
2010/04/28 Javascript
jQuery去掉字符串起始和结尾的空格(多种方法实现)
2013/04/01 Javascript
ie中js创建checkbox默认选中问题探讨
2013/10/21 Javascript
BOOTSTRAP时间控件显示在模态框下面的bug修复
2015/02/05 Javascript
剖析Node.js异步编程中的回调与代码设计模式
2016/02/16 Javascript
JavaScript鼠标特效大全
2016/09/13 Javascript
Node.js中文件操作模块File System的详细介绍
2017/01/05 Javascript
vue2.0父子组件及非父子组件之间的通信方法
2017/01/21 Javascript
详解通过JSON数据使用VUE.JS
2017/05/26 Javascript
前端主流框架vue学习笔记第一篇
2017/07/26 Javascript
ES6学习笔记之map、set与数组、对象的对比
2018/03/01 Javascript
Angular模版驱动表单的使用总结
2018/05/05 Javascript
jQuery表单元素过滤选择器用法实例分析
2019/02/20 jQuery
微信小程序收货地址API兼容低版本解决方法
2019/05/18 Javascript
Python实现二维数组按照某行或列排序的方法【numpy lexsort】
2017/09/22 Python
python中的内置函数max()和min()及mas()函数的高级用法
2018/03/29 Python
python删除不需要的python文件方法
2018/04/24 Python
Python两台电脑实现TCP通信的方法示例
2019/05/06 Python
python 多线程对post请求服务器测试并发的方法
2019/06/13 Python
Python hashlib加密模块常用方法解析
2019/12/18 Python
最新PyCharm从安装到PyCharm永久激活再到PyCharm官方中文汉化详细教程
2020/11/17 Python
Python字符串的15个基本操作(小结)
2021/02/03 Python
施华洛世奇天猫官方旗舰店:SWAROVSKI
2017/04/17 全球购物
英国在线药房:Chemist.co.uk
2019/03/26 全球购物
纬创Java面试题笔试题
2014/10/02 面试题
销售人员工作自我评价
2014/09/21 职场文书
社区领导班子四风问题原因分析及整改措施
2014/09/28 职场文书
2014年大学教师工作总结
2014/12/02 职场文书
2015小学教育教学工作总结
2015/07/21 职场文书
nginx基于域名,端口,不同IP的虚拟主机设置的实现
2021/03/31 Servers
sql server删除前1000行数据的方法实例
2021/08/30 SQL Server
CentOS7 minimal 最小化安装网络设置过程
2022/12/24 Servers