Python实现顺序表

2023-10-31

Python实现顺序表

关于顺序表的介绍,请参考:https://blog.csdn.net/weixin_43790276/article/details/103848039

Python 中的列表和元组都属于顺序表,下面根据顺序表的特性,自己来实现顺序表。

一、自定义一个顺序表类

在顺序表中,“表头”部分存储了当前顺序表的容量和已经有多少个数据。初始化一个顺序表时,需要按容量开辟一段内存来作为顺序表的数据存储空间,初始顺序表中的元素个数为0。

定义一个顺序表类 SequenceList ,初始化时可以指定顺序表的长度并开辟对应的存储空间,如默认长度为10,顺序表中的元素个数为0。

# coding=utf-8
class SequenceList(object):

    def __init__(self, max=10):
        self.max = max
        self.data = [None] * self.max
        self.num = 0

这样,就定义了一个顺序表类,实例化一个类对象就可以创建一个顺序表,只是还没有实现相应的功能。

二、实现顺序表的展示功能

    def is_empty(self):
        return self.num is 0

    def is_full(self):
        return self.num is self.max

    def show(self):
        print('<', end='')
        for i in range(0, self.num):
            if i != self.num-1:
                print(self.data[i], end=',')
            else:
                print(self.data[i], end='')
        print('>')

先实现判断顺序表是否为空的方法 is_empty() 和是否已满的方法 is_full(),这两个方法比较简单,如果顺序表中的数据是0个,则为空,如果数据数量已经达到了最大容量,则顺序表已满。

Python中的列表是用中括号,元组是小括号,所以也可以模仿,在展示自定义的顺序表时,使用尖括号,具体见 show() 方法。

if __name__ == '__main__':
    s = SequenceList()
    print("is_empty: ", s.is_empty())
    print("is_full: ", s.is_full())
    s.show()

运行结果:

is_empty:  True
is_full:  False
<>

三、实现顺序表中添加数据的功能

    def add(self, value):
        for j in range(self.num, 0, -1):
            self.data[j] = self.data[j-1]
        self.data[0] = value
        self.num += 1

    def append(self, value):
        self.data[self.num] = value
        self.num += 1

    def insert(self, i, value):
        if not isinstance(i, int):
            raise TypeError
        if i < 0:
            self.add(value)
        if i > self.num:
            self.append(value)
        for j in range(self.num, i, -1):
            self.data[j] = self.data[j-1]
        self.data[i] = value
        self.num += 1

    def count(self):
        return self.num

添加数据到顺序表中,可以从头部添加、从尾部添加或从指定位置添加。

add(value):从头部添加时,为了保证顺序表的顺序关系,原有的数据需要依次往后移动一个位置,所以从顺序表尾部开始遍历,将每个数据的索引值都加1,然后将添加的数据放在顺序表的第一个位置,添加完成后将顺序表的数量加1。

append(value):从尾部添加时,直接将数据添加在顺序表最后一个数据的后面,然后将顺序表的数量加1。

insert(i, value):在指定位置添加数据时,指定位置前面的数据不变,后面的数据都需要往后移动一个位置,所以从顺序表尾部开始遍历,将这些数据的索引值都加1,然后将添加的数据放在指定位置,再将顺序表的数量加1。

如果指定的位置是负数或超过了顺序表最大长度,则需要特殊处理,上面的处理是负数就在头部添加,超过最大长度就在尾部添加。也可以直接抛出 IndexError ,这个按需实现就可以了。

同时实现了查看顺序表长度的方法 count(),返回当前顺序表的数据个数。

    s.add(1)
    s.add(10)
    s.append(2)
    s.append(3)
    s.append(4)
    s.show()
    s.insert(1, 20)
    s.show()
    print("顺序表长度:", s.count())

运行结果:

<10,1,2,3,4>
<10,20,1,2,3,4>
顺序表长度: 6

四、实现顺序表的查询和修改功能

    def is_exist(self, value):
        for j in range(self.num):
            if self.data[j] == value:
                return True
        else:
            return False

    def index(self, value):
        for j in range(self.num):
            if self.data[j] == value:
                return j
        else:
            return -1

    def __getitem__(self, item):
        if not isinstance(item, int):
            raise TypeError
        if 0 <= item < self.num:
            return self.data[item]
        else:
            raise IndexError

    def __setitem__(self, key, value):
        if not isinstance(key, int):
            raise TypeError
        if 0 <= key < self.num:
            self.data[key] = value
        else:
            raise IndexError

在顺序表中添加数据后,就不再是一个空的表了。会有很多关于顺序表中的数据查询需求。

is_exist(value):判断一个数据是否存在顺序表中,遍历顺序表的每个数据,如果数据值与目标值相等,则说明顺序表中存在目标值。

index(value):返回一个数据在顺序表中的索引位置,与判断是否存在的实现方式一样,这里返回的是索引的值,如果顺序表中没有这个数据,则返回-1。

__getitem__(item):根据索引查询某个索引的数据,给定一个索引值,直接返回顺序表中该位置的数据即可,如果给的索引值超出了索引范围,应该直接抛出 IndexError 。这个方法之所以重写 Python 中的 __getitem__() 魔法方法,是因为 __getitem__() 实现了列表下标的方式来操作数据,支持 s[1] 这种类型的语法。这样写之后,既可以使用 s[1] 来获取顺序表中索引1的数据,也可以使用 s.__getitem__(1) ,结果相同。

__setitem__(key, value):修改指定位置的数据,先根据给定的索引值,找到顺序表中该索引的数据,然后修改。重写 __setitem__() 方法的原因与 __getitem__() 相同。

    s.show()
    print(s.is_exist(200))
    print(s.index(20))
    print(s.__getitem__(1))
    print(s[1])
    s[2] = 30
    s.__setitem__(3, 40)
    s.show()

运行结果:

<10,20,1,2,3,4>
False
1
20
20
<10,20,30,40,3,4>

五、实现顺序表的删除功能

    def remove(self, i):
        if not isinstance(i, int):
            raise TypeError
        if i < 0 or i >= self.num:
            raise IndexError
        for j in range(i, self.num):
            if j == self.num-1:
                self.data[j] = None
            else:
                self.data[j] = self.data[j+1]
        self.num -= 1

    def delete(self, value):
        for i in range(self.num):
            if self.data[i] == value:
                self.remove(i)
                return

    def delete_all(self, value):
        for i in range(self.num):
            if self.data[i] == value:
                self.remove(i)
                self.delete_all(value)

对顺序表执行删除操作之后,依然要保证顺序表中的数据顺序关系。

remove(i):删除指定索引的数据,删除指定索引位置的数据之后,该索引后面的数据都要依次往前移动。所以从指定索引的位置开始,依次将后一个位置的数据赋值给前一个位置,就实现了数据的删除。如果到了最后一个位置,则直接将它赋值为空就可以了。删除之后,顺序表的数量减1。

delete(value):删除指定值的数据,先遍历顺序表,找到对应值的索引,然后调用上面按索引删除的方法,即可删除指定的数据。使用这个方法,如果顺序表中有多个满足条件的数据,只会删除最前面的一个数据。

delete_all(value):删除所有相等的值,如果顺序表中有多个数据与指定值相等,删除第一个数据后,顺序表中数据的数量 self.num 会减1,继续遍历顺序表,会出现删除不完全甚至程序出错的情况。所以在删除第一个数据之后,递归调用自身,这样重新遍历时使用的是减1之后的 self.num ,不会出现漏删或错误。(也可以自己使用其他方式实现)

    s.show()
    s.remove(5)
    s.show()
    s.append(4)
    s.append(4)
    s.append(4)
    s.append(4)
    s.append(4)
    print("is_full: ", s.is_full())
    s.show()
    print("s的长度:", s.count())
    s.delete(4)
    s.show()
    s.delete_all(4)
    s.show()

运行结果:

<10,20,30,40,3,4>
<10,20,30,40,3>
is_full:  True
<10,20,30,40,3,4,4,4,4,4>
s的长度: 10
<10,20,30,40,3,4,4,4,4>
<10,20,30,40,3>

以上就是 Python 中顺序表及一些简单方法的实现。

上面的顺序表容量默认设置是10,如果超过10(可以改大)会报 IndexError ,使用时要注意。因为这个顺序表类中没有实现动态扩容的方法,不像 Python 中的列表有自动扩容的机制,如果需要的话可以继续实现扩容的方法。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python实现顺序表 的相关文章

  • Redis学习笔记五:redis主从复制

    通常使用redis时 如果redis存储的是一些非常重要的数据 那么只配置一台服务器的redis是有风险的 以为如果主服务器宕机 影响到正常业务之外 最终要的是数据的丢失 因此我们常常会配置多台redis做集群 除了防止主机宕机 我们还可以
  • 【AI视野·今日CV 计算机视觉论文速览 第166期】Mon, 28 Oct 2019

    AI视野 今日CS CV 计算机视觉论文速览 Mon 28 Oct 2019 Totally 47 papers 上期速览 更多精彩请移步主页 Interesting 联合显著性检测 提出了一种从单张图像中检测出具有相似语义属性的物体显著性
  • [转]一文看懂区块链架构设计 - 从概念到底层技术

    前言 区块链作为一种架构设计的实现 与基础语言或平台等差别较大 区块链是加密货币背后的技术 是当下与VR虚拟现实等比肩的热门技术之一 本身不是新技术 类似Ajax 可以说它是一种技术架构 所以我们从架构设计的角度谈谈区块链的技术实现 无论你
  • 广西人才网实习信息爬取与数据库存储实战

    广西人才网实习信息爬取与数据库存储实战 https www gxrc com 大家好 我是W 项目介绍 本项目为CrawlSpider结合MySQL MongoDB爬取求职网站信息的项目 目标是将网站指定分类下的招聘信息 包括 职位名称 公
  • Jupyter Notebook导入和删除虚拟环境

    在Jupyter Notebook中加载虚拟环境 比如现在我创建了一个虚拟环境名为pytorch 那么首先我先进入虚拟环境 activate pytorch Linux下需要使用source activate 然后运行 conda inst

随机推荐

  • Android init.rc整理

    AIL概述 init rc由AIL语言编写而成 可以参考system core init README md来学习AIL语法相关知识 不同Android版本关于AIL的说明存在一些细微差异 但基本语法和总的思路是不变的 往往我们可以先查看对
  • 2021哈工大机器翻译实验室经验贴(回忆版)

    哈工大机器翻译实验室 有两轮 一轮笔试 一轮面试 第一轮笔试题 根据本人的回忆 3道简答 5道编程题 60分钟 一 简答题 1 Windows下的软件Office 在Ubuntu环境下能否运行 说明理由 2 已知账户名和账户密码 说明登录到
  • 反射与线程间通讯

    反射 一 在运行状态中 对于任意一个类 都能够获取到这个类的所有属性和方法 对于任意一个对象 都能够调用它的任意一个方法和属性 包括私有的方法和属性 这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制 通俗点讲 通过
  • 设置linearlayout最大高度_数据中心:主要设备用房高度需求及建筑层高规划

    主要设备用房高度需求 数据中心主要设备用房为35KV开闭所 10KV开闭所 低压变配电房 动力 低压变配电房 IT UPS 柴油发电机组 冷冻机房 IT机房模块间等 35KV开闭所通常单独设置不在IT机房大楼内布置 本文不再讨论 各设备用房
  • Nginx服务优化

    配置nginx隐藏版本号 隐藏nginx版本号 避免安全漏洞泄漏 方法一 修改配置文件法 root www conf vim usr local nginx confnginx conf 17 http 18 include mime ty
  • 图解---散列表(hash表)的基本原理以及hash冲突(碰撞)--易懂版

    图解 散列表 hash表 的基本原理以及hash冲突 碰撞 易懂版 散列表为什么诞生 它用于做什么 先说说数组 数组的优点是查找比较快 但是添加和删除效率比较低 再说说链表 链表的优点是添加和删除效率比较快 相对于数组 但是遍历需要一个指针
  • 一种软件网络验证方式的实现 + 网络验证转本地验证的一种实现(附VC源码)...

    目前很多软件都是通过网络验证来实现的 一种比较流行的方式便是把服务器端 如验证网页 放在服务器上 软件为客户端 当软件注册或启动时通过网络与服务器端进行数据交换 重新实现验证的目的 个人觉得网络验证将是一种趋势 做得好的网络验证方式将是对软
  • Spring 源码 事件监听

    2019独角兽企业重金招聘Python工程师标准 gt gt gt spring 监听器 一 事件监听机制概述 二 事件监听机制结构 三 Spring监听机制架构 Spring的Application拥有发布事件并且注册事件监听器的能力 拥
  • python验证码识别MuggleOCR通用识别使用

    先来看看MuggleOCR简介 白嫖 这是一个为麻瓜设计的本地OCR模块 只需要简单几步操作即可拥有两大通用识别模块 让你在工作中畅通无阻 这套模型是基于 https github com kerlomz captcha trainer 训
  • JSP注释(4种)

    说到注释 相信大家肯定都不陌生 它是对程序代码的解释和说明 注释可以提高代码的可读性 让他人能够更加轻松地了解代码 从而提高团队合作开发的效率 在 JSP 中可以使用以下 4 种注释 HTML 注释 带有 JSP 表达式的注释 隐藏注释 脚
  • 登录和注册的基本实现,超简单!

    前序 相信有很多的人在刚刚做项目的实现 登录与注册功能的实现是基本的要求 要是刚刚开始写的小伙伴肯定会有很多的困惑 这里我介绍一下自己的写法 希望能帮到你 也希望能免费点个小 这里就以之前我写的一个为例 大家可以根据自己的规则来更改 一 登
  • python 短路法提高二叉堆插入效率

    在学习 problem solving with algorithms and data structure using python 中的二叉堆时 其插入数据方法是将这个数据放在列表的尾部 然后通过一次次与父节点进行比较 并且交换 实现顺
  • 用Log4j 2记录日志

    说明 maven工程中增加对Log4j 2的依赖 下面代码示例的maven工程中的pom xml文件中需要增加对Log4j 2的依赖
  • -moz-transform:rotate()

    目前越来越多的浏览器兼容CSS3标准了 就连IE浏览器老大哥也开始向CSS3低头 微软宣布IE9浏览器支持更多的CSS3属性 IE9更注重HTML5标准 不过CSS3里有一个使对象旋转的属性transform rotate 号称兼容CSS3
  • 2023高教社杯 国赛数学建模B题思路 - 多波束测线问题

    1 赛题 B 题 多波束测线问题 单波束测深是利用声波在水中的传播特性来测量水体深度的技术 声波在均匀介质中作匀 速直线传播 在不同界面上产生反射 利用这一原理 从测量船换能器垂直向海底发射声波信 号 并记录从声波发射到信号接收的传播时间
  • springboot定时任务

    1 配置 在主函数加 EnableScheduling 定时任务 package com biubiu import org springframework boot SpringApplication import org springf
  • golang的web框架Gin(一)---Gin的安装与初体验

    简介 1 1 介绍 Go世界里最流行的Web框架 Github上有32K star 基于httprouter开发的Web框架 中文文档齐全 简单易用的轻量级框架 Gin是一个golang的微框架 封装比较优雅 API友好 源码注释比较明确
  • [已解决]运行 ‘tomcat8‘ 出错: 无法打开调试器端口 (127.0.0.1:6672): java.net.SocketException

    解决 运行 tomcat8 出错 无法打开调试器端口 127 0 0 1 6672 java net SocketException 修改HTTP port端口号 没占用的端口号都可以 建议8000以上的数字 只要不是现在的端口号就可以 修
  • ARM(IMX6U)裸机按键输入实验(BSP+SDK、GPIO输入与输出、按键消抖)

    参考 Linux之ARM IMX6U 裸机按键输入实验 GPIO的输出与输入 作者 一只青木呀 发布时间 2020 08 17 21 43 37 网址 https blog csdn net weixin 45309916 article
  • Python实现顺序表

    Python实现顺序表 关于顺序表的介绍 请参考 https blog csdn net weixin 43790276 article details 103848039 Python 中的列表和元组都属于顺序表 下面根据顺序表的特性 自