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中使用urllib2模块编写爬虫的简单上手示例
Jan 20 Python
学习python 之编写简单乘法运算题
Feb 27 Python
python3读取MySQL-Front的MYSQL密码
May 03 Python
使用Django连接Mysql数据库步骤
Jan 15 Python
selenium python 实现基本自动化测试的示例代码
Feb 25 Python
详解python中的time和datetime的常用方法
Jul 08 Python
python操作openpyxl导出Excel 设置单元格格式及合并处理代码实例
Aug 27 Python
解决python 文本过滤和清理问题
Aug 28 Python
浅谈python出错时traceback的解读
Jul 15 Python
深入了解Python enumerate和zip
Jul 16 Python
Django项目创建及管理实现流程详解
Oct 13 Python
python如何查找列表中元素的位置
May 30 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
ninety plus是什么?ninety plus咖啡好吗?
2021/03/04 新手入门
php通过pecl方式安装扩展的实例讲解
2018/02/02 PHP
浅谈PHP匿名函数和闭包
2019/03/08 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
2020/03/29 PHP
editable.js 基于jquery的表格的编辑插件
2011/10/24 Javascript
jquery1.9 下检测浏览器类型和版本的方法
2013/12/26 Javascript
一个JavaScript递归实现反转数组字符串的实例
2014/10/14 Javascript
javascript编写贪吃蛇游戏
2015/07/07 Javascript
jQuery移动web开发之页面跳转和加载外部页面的实现
2015/12/04 Javascript
JS简单实现String转Date的方法
2016/03/02 Javascript
对Angular.js Controller如何进行单元测试
2016/10/25 Javascript
基于Vue渲染与插件的加载顺序的问题详解
2018/03/05 Javascript
vue写一个组件
2018/04/09 Javascript
用Electron写个带界面的nodejs爬虫的实现方法
2019/01/29 NodeJs
ES6入门教程之变量的解构赋值详解
2019/04/13 Javascript
vue router 用户登陆功能的实例代码
2019/04/24 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
2019/05/10 Javascript
VScode格式化ESlint方法(最全最好用方法)
2019/09/10 Javascript
[51:34]Ti4主赛事胜者组 DK vs EG 2
2014/07/19 DOTA
[07:38]2014DOTA2国际邀请赛 Newbee顺利挺进胜者组赛后专访
2014/07/15 DOTA
[03:39]这就是刀塔,我们是冠军!燃情短片讲述我们的DOTA故事
2019/07/02 DOTA
Python实现一个转存纯真IP数据库的脚本分享
2017/05/21 Python
浅谈django orm 优化
2018/08/18 Python
Python 忽略warning的输出方法
2018/10/18 Python
python模块之subprocess模块级方法的使用
2019/03/26 Python
django url到views参数传递的实例
2019/07/19 Python
wxPython多个窗口的基本结构
2019/11/19 Python
Tensorflow之梯度裁剪的实现示例
2020/03/08 Python
Python中使用filter过滤列表的一个小技巧分享
2020/05/02 Python
Python reduce函数作用及实例解析
2020/05/08 Python
澳大利亚手表品牌:Time IV Change
2018/10/06 全球购物
超市促销活动方案
2014/03/05 职场文书
领导接待方案
2014/03/13 职场文书
2015年企业员工工作总结范文
2015/05/21 职场文书
优秀党员主要事迹范文
2015/11/05 职场文书
Python基础数据类型tuple元组的概念与用法
2021/08/02 Python