线性表和链表

news2024/11/27 6:13:39

一,线性结构

1.Array

Array文档:可以自行阅读相关文档来了解Array

class array.array(typecode[, initializer])

 

 

array.append(x):添加元素到数组末尾

array.count(x):计算元素出现次数

array.extend(iterable):将迭代器中的元素依次添加到数组末尾,不过要注意元素的类型要一致,要不然会抛出TypeError

array.fromfile(fn):读取文件中n个元素,如果文件中元素数量小于n,抛出EOFError,不过之前写入的数据仍然存在。

array.fromlist(list):与上例差不多,相当于for x in list: a.append(x),类型要一致。

array.fromstring(s):与上例差不多。

array.index(x):返回第一次元素出现的下标。

array.insert(ix):将元素x插入到i的位置上。

array.pop([i]):移除i下标的元素并且返回这个值,默认-1(最后一个)。

array.remove(x):移除掉第一个x元素,不对后续x元素处理。

array.reverse():反转数组。

array.tofile(f):把数组内容写到文件中。

array.tolist():把数组转化为列表,不改变内容。

array.tostring():把数组转化为字符串。

array.tounicode():和tostring差不多,但是要注意数组类型是'u'。要不然会抛出ValueError。

文档内容差不多就这些,大部分是写方法,加粗的为不常用的,还有一些方法会有些版本限制,稍微注意。

2.List实现Array部分功能

 

3.代码实现

class Array():
    def __init__(self,size):
        self.__size = size
        self.__item = [None]*size
        self.__length = 0

    def __setitem__(self,key,value):
        self.__item[key] = value
        self.__length += 1

    def __getitem__(self, index):
        return self.__item[index]

    def __len__(self):
        return self.__length

    def __iter__(self):
        for value in self.__item:
            yield value

    def remove(self,value):
       for i,ele in enumerate(self.__item):
           if ele == value:
               self.__item[i] = None
       return


if __name__ == '__main__':
    a1 = Array(10)
    a1[0] = 1
    a1[1] = 2
    a1[2] = 3
    a1[3] = 4
    a1.remove(2)

    for value in a1:
        print(value)



 

 

二,链式结构

1.单链表

1.基本原理

和线性结构不同,链式结构内存不连续的,而是一个个串起来的,这个时候就需要每个链接表的节点保存一个指向下一个节点的指针。 这里可不要混淆了列表和链表(它们的中文发音类似,但是列表 list 底层其实还是线性结构,链表才是真的通过指针关联的链式结构)。 看到指针你也不用怕,这里我们用的 python,你只需要一个简单赋值操作就能实现,不用担心 c 语言里复杂的指针。

先来定义一个链接表的节点,刚才说到有一个指针保存下一个节点的位置,我们叫它 next, 当然还需要一个 value 属性保存值。

class Node:
    def __init__(self, value, next=None):
        self.value = value
        self.next = next

然后就是我们的单链表 LinkedList ADT:

class LinkedList(object):
    """ 链接表 ADT
    [root] -> [node0] -> [node1] -> [node2]
    """

 

 

2.代码实现

class Node():
    def __init__(self,value=None,next=None):
        self.value = value
        self.next = next

    def __str__(self):
        return 'Node:{}'.format(self.value)


class LinkedList():
    def __init__(self):
        self.root = Node()
        self.size = 0
        self.next = None#增加新数据时,将新数据地址与谁关联

    def append(self,value):
        node = Node(value)
        if not self.next:
            self.root.next = node
        else:
            self.next.next = node
        self.next = node
        self.size += 1

    def append_first(self,value):
        node = Node(value)
        if not self.next:
            self.root.next = node
            self.next = node
        else:
            temp = self.root.next
            self.root.next = node
            node.next = temp
        self.size += 1

    def __iter__(self):
        current = self.root.next
        if current:
            while current is not self.next:
                yield current
                current = current.next
            yield current
    def find(self,value):
        for n in self.__iter__():
            if n.value == value:
                return n
    def find_count(self,value):
        count = 0
        for n in self.__iter__():
            if n.value == value:
                count += 1
        return count

    def remove(self,value):
        prev = self.root
        for n in self.__iter__():
            if n.value == value:
                if n == self.next:
                    prev.next == None
                    self.next = prev
                prev.next = n.next
                del n
                self.size -= 1
                return True
            prev = n

    def remove_all(self,value):
        prev = self.root
        for n in self.__iter__():
            if n.value == value:
                if n == self.next:
                    prev.next == None
                    self.next = prev
                prev.next = n.next
                del n
                self.size -= 1
                continue
            prev = n






if __name__ == '__main__':
    link = LinkedList()
    link.append(11)
    link.append(11)
    link.append(11)
    link.append(14)
    link.append(15)
    link.append(16)
    for value in link:
        print(value)
    print(link.find(11))
    print(link.find_count(11))
    link.remove(16)
    for value in link:
        print(value)
    link.remove_all(11)
    print("--"*20)
    for value in link:
        print(value)


 

2.双链表

上边我们亲自实现了一个单链表,但是能看到很明显的问题,单链表虽然 append 是 O(1),但是它的 find 和 remove 都是 O(n)的, 因为删除你也需要先查找,而单链表查找只有一个方式就是从头找到尾,中间找到才退出。 我们需要在一个链表里能高效的删除元素, 并把它追加到访问表的最后一个位置,这个时候单链表就满足不了了。

1.基本原理

这里就要使用到双链表了,相比单链表来说,每个节点既保存了指向下一个节点的指针,同时还保存了上一个节点的指针。

class Node(object):
    def __init__(self, value=None, prev=None, next=None):
        self.value, self.prev, self.next = value, prev, next
  • 看似我们反过来遍历双链表了。反过来从哪里开始呢?我们只要让 root 的 prev 指向 tail 节点,不就串起来了吗?
  • 直接删除节点,当然如果给的是一个值,我们还是需要查找这个值在哪个节点? - 但是如果给了一个节点,我们把它拿掉,直接让它的前后节点互相指过去不就行了?哇欧,删除就是 O(1) 了,两步操作就行啦

 

 

 

2.代码实现

class Node():
    def __init__(self,value=None,prev=None,next=None):
        self.value = value
        self.next = next
        self.prev = prev
    def __str__(self):
        return "Node:{}".format(self.value)

class DoubleLinkedList():
    def __init__(self):
        self.size = 0
        self.root = Node()
        self.end = None

    def append(self,value):
        node = Node(value=value)
        #无节点
        if not self.end:
            self.root.next = node  # root节点指向新节点
            node.prev = self.root#新节点指向根节点
            self.end = node#末节点指针指向新节点


        #有节点
        else:
            self.end.next = node#末节点指向新节点
            node.prev = self.end  # 新节点指向末节点
            self.end = node#末节点移动到新节点
        self.size += 1

    def append_first(self,value):
        node = Node(value=value)
        #无节点
        if not self.end:
            self.root.next = node  # root节点指向新节点
            node.prev = self.root  # 新节点指向根节点
            self.end = node  # 末节点指针指向新节点
        else:
            node.prev = self.root#新节点指向根节点
            temp = self.root.next#保存原来的第一个节点
            self.root.next = node#将新节点替换为第一个节点
            node.next = temp#让新节点的下一个节点为原来的第一个节点
            temp.prev = node#将原来的第一个节点的上一个节点设置为新节点
        self.size += 1


    def __iter__(self):
        current = self.root.next
        if current:
            while current is not self.end:
                yield current
                current = current.next
            return current
        else:
            print("LinkedList is empty")

    #逆向迭代
    def inverse_iter(self):
        current = self.end
        if current:
            while current is not self.root:
                yield current
                current = current.prev
        else:
            print("LinkedList is empty")

    def find(self,value):
        pass

    def find_count(self,value):
        pass

    def remove(self,value):
        pass

    def remove_all(self,value):
        pass

if __name__ == '__main__':
    link = DoubleLinkedList()
    link.append(11)
    link.append(12)
    link.append(13)
    link.append(14)
    link.append(15)

    gen = (link.inverse_iter())
    for value in gen:
        print(value)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1803024.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ipables防火墙

一、Linux防火墙基础 Linux 的防火墙体系主要工作在网络层,针对 TCP/IP 数据包实施过滤和限制,属于典 型的包过滤防火墙(或称为网络层防火墙)。Linux 系统的防火墙体系基于内核编码实现, 具有非常稳定的性能和高效率&…

SpringBoot的Mapper文件什么时候需要使用@Param注解

解决:nested exception is org.apache.ibatis.binding.BindingException: Parameter ‘XXX‘ not found 关于加注解,其他博客说的很清楚!但是有的人会遇见明明使用的springboot2.x以上版本,仍然提示需要加注解!这是为…

SQL Server设置默认Schema (修正运行版)

目录 方法 1:执行 USE 命令 方法 2:执行 ALTER USER 命令 方法 3:在查询中包含Schema 总结 在 SQL Server 中,通过 JDBC 设置会话的默认Schema并不是很直接,但可以使用一些变通方法来实现。以下是一些管理默认Sche…

sub_mch_id 与 sub_appid 不匹配怎么解决

小程序在支付的时候,有时候会碰到:sub_mch_id 与 sub_appid 不匹配的问题。这个问题意味着小程序微信支付时所使用的 sub_mch_id(子商户号)和 sub_appid(小程序的appId)不对应。下面就具体介绍如何核对是否…

解决 There is no getter for property named ‘null‘ in ‘class 报错

1. 问题 mybatis-plus在更新删除操作时报错 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession750ee72a] 2024-06-08 21:03:07 [http-nio-8080-exec-3] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servl…

Kubernetes 基础架构最佳实践:从架构设计到平台自动化

本文探讨了如何将DigitalOcean Kubernetes (DOKS)应用于生产环境,并提供实现生产准备(production readiness)的指导。 规划您的基础架构 Kubernetes 基础架构的规划至关重要,因为它为稳定且可扩展的应用部署平台奠定了基础。通过适…

Python采集东方财富网股票数据建立LSTM模型预测

Python采集东方财富网股票数据建立LSTM模型预测 一、数据爬取流程二、爬虫完整代码三、LSTM模型建模预测3.1 项目背景3.2 建模预测流程3.3 数据预处理3.4 数据可视化3.5 特征工程3.6 数据缩放3.7 数据转换3.8 模型创建3.9 评价模型3.10 可视化结果3.11 总结一、数据爬取流程 先…

107.网络游戏逆向分析与漏洞攻防-装备系统数据分析-装备信息更新的处理

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 如果看不懂、不知道现在做的什么,那就跟着做完看效果 现在的代码都是依据数据包来写的,如果看不懂代码,就说明没看懂数据包…

实战 | 通过微调SegFormer改进车道检测效果(数据集 + 源码)

背景介绍 SegFormer:实例分割在自动驾驶汽车技术的快速发展中发挥了关键作用。对于任何在道路上行驶的车辆来说,车道检测都是必不可少的。车道是道路上的标记,有助于区分道路上可行驶区域和不可行驶区域。车道检测算法有很多种,每…

【Unity3D小功能】Unity3D中UGUI-Text实现打字机效果

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群:398291828 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 需求要实现Text的打字机效果,一看居然…

实战 | YOLOv10 自定义数据集训练实现车牌检测 (数据集+训练+预测 保姆级教程)

导读 本文主要介绍如何使用YOLOv10在自定义数据集训练实现车牌检测 (数据集训练预测 保姆级教程)。 YOLOv10简介 YOLOv10是清华大学研究人员在Ultralytics Python包的基础上,引入了一种新的实时目标检测方法,解决了YOLO以前版本在后处理和模型架构方面…

挂上了代理加速器梯子之后,Git clone指令下载仍旧很慢的问题

当你使用了各种代理软件访问诸如Github、Google、油管、推特这些网址,你会发现基本可以访问,只不过是访问速度不同,但是不管你使用什么代理软件,你的git clone指令从Github远程库下载库的速度都不会受到影响。 当使用代理软件访问…

LIP模型动力学方程例子

线性倒立摆(Linear Inverted Pendulum, LIP)模型是用于描述和控制人形机器人步态的重要工具。LIP模型假设质心沿着一条固定的直线运动,并且所有质量集中在质心上。这简化了计算,使得模型更容易用于控制和稳定分析。 LIP模型动力学方程 LIP模型的基本假设是: 机器人的质心…

【原创】海为PLC与RS-WS-ETH-6传感器的MUDBUS_TCP通讯

点击“蓝字”关注我们吧 一、关于RS-WS-ETH-6传感器的准备工作 要完成MODBUS_TCP通讯,我们必须要知道设备的IP地址如何分配,只有PLC和设备的IP在同一网段上,才能建立通讯。然后还要选择TCP的工作模式,来建立设备端和PC端的端口号。接下来了解设备的报文格式,方便之后发送…

如何有效释放Docker占用的存储空间

随着Docker的广泛应用,我们经常会遇到Docker占用过多存储空间的问题。这可能是由于频繁的镜像拉取、容器创建和删除等操作导致的。本文将介绍几种方法来有效释放Docker占用的存储空间,特别是docker system prune命令的使用。 Docker的存储机制 Docker使…

浔川python社官方警告——浔川总社部、浔川社团举报中心

昨天,浔川社团举报中心接到举报,说有被侵权文章。 今天,小编再搜索“怎么加入浔川python社”时 ,看到了假冒浔川python社的网站。 该网站我社团并不认识,并且侵权了我社 《用python做的一个登录界面——浔川python社》…

海思SS928(SD3403)部署YOLOv5-YOLOv7步骤详解

1. YOLO模型资料 本文档内容以yolov5-7.0工程、yolov5s模型为例。 a. 模型结构 详细的模型结构可以利用netron工具打开.pt或.onnx模型查看。 b. 模型参数即验证结果 其中,YOLOv5n、YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x为五种类型的预训练模型,其包含的检测类别相…

vue element 接口返回数据与控制台打印数据不一致 踩坑

问题描述: 接口返回数据正常,,控制台打印不对,element el-switch表格中使用,控制台打印数据被改变 如下正常数据 数据id 17状态是0 控制台打印状态却是1 造成原因: element el-seitch组件修改了状态 修…

【Vue】声明式导航-导航链接

文章目录 一、引入二、解决方案三、代码示例四、声明式导航-两个类名1)router-link-active2)router-link-exact-active 一、引入 但凡说到声明式导航,都需要想到router-link 需求 实现导航高亮效果 如果使用a标签进行跳转的话,需要…

TensorFlow2.x基础与mnist手写数字识别示例

文章目录 Github官网文档Playground安装声明张量常量变量 张量计算张量数据类型转换张量数据维度转换ReLU 函数Softmax 函数卷积神经网络训练模型测试模型数据集保存目录显示每层网络的结果 TensorFlow 是一个开源的深度学习框架,由 Google Brain 团队开发和维护。它…