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的Bottle框架中返回静态文件和JSON对象的方法
Apr 30 Python
python清除字符串里非数字字符的方法
Jul 02 Python
Python HTTP客户端自定义Cookie实现实例
Apr 28 Python
详谈Python高阶函数与函数装饰器(推荐)
Sep 30 Python
在scrapy中使用phantomJS实现异步爬取的方法
Dec 17 Python
GDAL 矢量属性数据修改方式(python)
Mar 10 Python
Pycharm pyuic5实现将ui文件转为py文件,让UI界面成功显示
Apr 08 Python
利用jupyter网页版本进行python函数查询方式
Apr 14 Python
13个Pandas实用技巧,助你提高开发效率
Aug 19 Python
python实现快速文件格式批量转换的方法
Oct 16 Python
Python多个MP4合成视频的实现方法
Jul 16 Python
Python实现视频自动打码的示例代码
Apr 08 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扩展vld查看PHP opcode操作步骤
2013/03/04 PHP
ThinkPHP CURD方法之data方法详解
2014/06/18 PHP
golang、python、php、c++、c、java、Nodejs性能对比
2017/03/12 NodeJs
PHP长网址与短网址的实现方法
2017/10/13 PHP
PHP实现基于栈的后缀表达式求值功能
2017/11/10 PHP
实现php删除链表中重复的结点
2018/09/27 PHP
js中将多个语句写成一个语句的两种方法小结
2007/12/08 Javascript
javascript处理table表格的代码
2010/12/06 Javascript
jQuery浏览器CSS3特写兼容实例
2015/01/19 Javascript
微信小程序 图片等比例缩放(图片自适应屏幕)
2016/11/16 Javascript
Vue shopCart 组件开发详解
2018/01/26 Javascript
小程序云开发初探(小结)
2018/10/24 Javascript
vue指令之表单控件绑定v-model v-model与v-bind结合使用
2019/04/17 Javascript
JS字符串常用操作方法实例小结
2019/06/24 Javascript
pageGroup.js实现分页功能
2019/07/27 Javascript
Vue+Koa2 打包后进行线上部署的教程详解
2019/07/31 Javascript
javascript实现留言板功能
2020/02/08 Javascript
Nuxt页面级缓存的实现
2020/03/09 Javascript
vue2.0实现列表数据增加和删除
2020/06/17 Javascript
Python中用函数作为返回值和实现闭包的教程
2015/04/27 Python
动感网页相册 python编写简单文件夹内图片浏览工具
2016/08/17 Python
Python数据操作方法封装类实例
2017/06/23 Python
Pycharm导入Python包,模块的图文教程
2018/06/13 Python
python使用paramiko模块通过ssh2协议对交换机进行配置的方法
2019/07/25 Python
Python中格式化字符串的四种实现
2020/05/26 Python
浅析关于Keras的安装(pycharm)和初步理解
2020/10/23 Python
CSS3 实现雷达扫描图的示例代码
2020/09/21 HTML / CSS
英国复古服装和球衣购买网站:3Retro Football
2018/07/09 全球购物
希腊品牌鞋类销售网站:epapoutsia.gr
2020/03/18 全球购物
中学老师的自我评价
2013/11/07 职场文书
远程教育心得体会
2014/01/03 职场文书
幼儿教师自我剖析材料
2014/09/29 职场文书
学校社团活动总结
2015/05/07 职场文书
2015年超市工作总结范文
2015/05/26 职场文书
HTML中table表格拆分合并(colspan、rowspan)
2021/04/07 HTML / CSS
js 实现验证码输入框示例详解
2022/09/23 Javascript