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获取邮件地址的方法
Jul 10 Python
Python装饰器原理与简单用法实例分析
Apr 29 Python
python3.4控制用户输入与输出的方法
Oct 17 Python
python pandas消除空值和空格以及 Nan数据替换方法
Oct 30 Python
Python实现的排列组合、破解密码算法示例
Apr 12 Python
解决python xx.py文件点击完之后一闪而过的问题
Jun 24 Python
让Python脚本暂停执行的几种方法(小结)
Jul 11 Python
详解python路径拼接os.path.join()函数的用法
Oct 09 Python
Python-jenkins模块获取jobs的执行状态操作
May 12 Python
Python实现寻找回文数字过程解析
Jun 09 Python
Python如何实现后端自定义认证并实现多条件登陆
Jun 22 Python
python爬虫使用requests发送post请求示例详解
Aug 05 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
各种战术和打法的原创者
2020/03/04 星际争霸
Javascript miscellanea -display data real time, using window.status
2007/01/09 Javascript
用于判断用户注册时,密码强度的JS代码
2009/01/01 Javascript
Javascript Cookie读写删除操作的函数
2010/03/02 Javascript
js中更短的 Array 类型转换
2011/10/30 Javascript
Jquery 自定义动画概述及示例
2013/03/29 Javascript
js确认删除对话框适用于a标签及submit
2014/07/10 Javascript
JS的框架Polymer中的dom-if和is属性使用说明
2015/07/29 Javascript
JavaScript实现图片滑动切换的代码示例分享
2016/03/06 Javascript
使用jQuery制作浮动工具栏的实例分享
2016/05/13 Javascript
JavaScript绑定事件监听函数的通用方法
2016/05/14 Javascript
XMLHttpRequest Level 2 使用指南
2016/08/26 Javascript
js实现获取鼠标当前的位置
2016/12/14 Javascript
jQuery实现验证码功能
2017/03/17 Javascript
angularJS深拷贝详解
2017/03/23 Javascript
JS的函数调用栈stack size的计算方法
2018/06/24 Javascript
Vue axios设置访问基础路径方法
2018/09/19 Javascript
Koa 中的错误处理解析
2019/04/09 Javascript
LayUI动态设置checkbox不显示的解决方法
2019/09/02 Javascript
[00:32]DOTA2上海特级锦标赛 COL战队宣传片
2016/03/04 DOTA
[05:09]2016国际邀请赛中国区预选赛淘汰赛首日精彩回顾
2016/06/29 DOTA
[02:03]永远的信仰DOTA2 中国军团历届国际邀请赛回顾
2016/06/26 DOTA
[58:21]DOTA2亚洲邀请赛 4.3 突围赛 Liquid vs VGJ.T 第二场
2018/04/04 DOTA
用python代码做configure文件
2014/07/20 Python
《Python之禅》中对于Python编程过程中的一些建议
2015/04/03 Python
总结Python编程中函数的使用要点
2016/03/20 Python
python使用matplotlib绘图时图例显示问题的解决
2017/04/27 Python
Django自定义认证方式用法示例
2017/06/23 Python
基于python进行桶排序与基数排序的总结
2018/05/29 Python
tensorflow 限制显存大小的实现
2020/02/03 Python
PyCharm 2020.2.2 x64 下载并安装的详细教程
2020/10/15 Python
Python调用JavaScript代码的方法
2020/10/27 Python
俄罗斯EPL钻石珠宝店:ЭПЛ
2019/10/22 全球购物
描述一下JVM加载class文件的原理机制
2013/12/08 面试题
JPA的特点
2014/10/25 面试题
2016高考感言
2015/08/01 职场文书