数据结构与算法 【Python】

本文详细探讨了Python中的数据结构,包括抽象数据类型、线性表(链表)、字符串、栈、队列、二叉树、图、字典和集合。重点讲解了线性表的顺序表和链表实现,以及链表的单链表操作。此外,还介绍了字符串操作、正则表达式、栈和队列的概念,以及二叉树和图的性质。文章深入浅出地阐述了数据结构和算法在Python中的应用。
摘要由CSDN通过智能技术生成

在这里插入图片描述

数据结构:
想通过计算机解决一个实例问题,需要输入信息A,然后通过在计算机上运行程序,产出以另一种方式输出的信息B。那么就可以认为这个程序完成了该问题实例的求解工作。

  • 信息:可以是数字、图像、语音等等有内容的东西
  • 数据:在计算机科学领域,数据指计算机(程序)能够处理的符号形式的总和
  • 数据元素:在讨论计算机处理时,指最基本的数据单位。在计算机硬件层面,所有被存储和处理的数据最终都编码为二进制代码形式,一切数据最终都表现为二进制位的序列,最基本的数据元素就是一个二进制位。
  • 数据结构:数据间的关联和组合形式,总结其中的规律性,发掘特别值得注意的有用结构,研究这些结构的性质,从而研究如何在计算机中实现这些有用的数据结构,以支持相应组合数据的高效使用,支持处理它们的高效算法。

Python变量与对象
Python变量的值都是对象,可以是基本整数、浮点数等类型的对象,也可以是组合类型的对象,如 list等。程序中建立和使用的各种复杂对象,包括Python函数等,都基于独立的存储块实现,通过链接相互关联。程序里的名字(变量、参数、函数名等)关联着作为其值的对象,这种关联可以用赋值操作改变。

Python对象的表示
Python程序内部有一个存储管理系统,负责管理可用内存,为各种对象安排存储,支持灵活有效的内存使用。程序中要求建立对象时,管理系统就会为其安排存储,某些对象不再有用时,就会则收回其占用的存储。存储管理系统屏蔽了集体内存使用的细节,大大减少了编程人员的负担。

一、抽象数据类型和Python类

1、数据类型和数据构造

类型(数据类型)是程序设计领域最重要的基本概念之一。

  • 逻辑类型 bool:包括两个值(两个对象)True 和 False,可用操作包括 and、or、not
  • 数值类型 int 和 float:int类型包含很多值(整数对象),对它们可以做加减乘除等运算
  • 字符串类型 str
  • 还会有一些 组合数据类型(下面讲到的list、tuple、set、dict等结构)

但是,无论编程语言提供了多少内置类型,在处理较为复杂的问题时,程序员或早或晚都会遇到一些情况,内置类型难以满足需要,这时就出现了:

list、tuple、set、dict 等结构(它们也看做是类型),编程时可以利用它们把一组相关数据组织在一起,作为一个数据对象,作为一个整体存储、传递和处理。

总结:

  • 1、基本的数据类型包括

1. Number ( 数值 ) ----> 整型 int,浮点型 float
2. String( 字符串 )
3. Tuple( 元组 )-----------------> ( , , , , )

4. List( 列表 ) -------------------> [ , , , , ]
5. set ( 集合 ) -------------------> { ’ ’ , ’ ’ , ’ ’ }
6. Dictionary( 字典 )------------> { " " : 123 , " " : 789 }

可变数据 和 不可变数据 的区分:

不可变数据(3个):Number(数字)、String(字符串)、Tuple(元组)
可变数据(3个):List(列表)、Dictionary(字典)、set(集合)

  • 2、数据类型的创建方式

创建 列表listT = [ 1, 2, 3, 4, 5 ]
创建 元组tup2 = ( 1, 2, 3, 4, 5 )
创建 字典dict2={ “abc”:123, “def”:789 }
创建 集合student={ ‘Tom’ , ‘Jim’ , ‘Mary’ }

2、抽象数据类型的概念

抽象数据类型的基本想法是把数据定义为抽象的对象集合,只为它们定义可用的合法操作,并不暴露其内部实现的具体细节,不论是其数据的表示细节还是操作的实现细节。

当然要使用一种对象,首先需要能构造这种对象,然后操作它们。

数据类型有个很重要的性质,叫 变动性,表示该类型的对象在创建之后是否允许变化。

  • 不变(数据)类型:str、tuple、frozenset
  • 可变(数据)类型:list、set、dict

在编程中设计或定义抽象数据类型时,也要根据情况,决定将其定义为不变类型 还是 可变类型。

1.抽象数据类型(Abstract Data Type , ADT)

ADT的概念:拥有属性和方法,属性可以存储数据,方法操作属性(增删改查)
ADT的思想:就是抽象,或者说 数据抽象,
咱们通常定义一个类,例如:

class animal()

属性 -----> 干啥用的呢?描述这个animal类的,一个名词性的描述
方法 -----> 这个类所具有的功能

你比如列表最典型了,list 点进去,里面有一堆def方法,说列表干啥干啥,但所有def上面的那一小块属性是说明list是具有存数据的功能的。
在这里插入图片描述

抽象数据类型呢,就是把上面那个属性私有,然后来提供一些方法,这些方法操纵属性,这个属性在抽象数据类型里的作用和目的就是存数据的,

class int 里面也有个
属性是存数据的( 存储 int 类型数据),然后还有方法是对这个属性进行操作的,

class mylist():
     def __init__(self,element):
         self.__element = element
     def delete(self):     # 执行删除操作
         del self.__element
     def set_element(self,element):   # 执行重新赋值
         self.__element = element
     def get_element(self):   # 查看
         return self.__element

ml = mylist([1,4,5,6])
# ml.delete()
print(ml.get_element())

在这里插入图片描述
上述显示结果是获取不到列表,
在这里插入图片描述
上面两幅截图的对比,得出的结论就是:一个抽象数据类型包括两部分:存储数据的属性__init__和操作属性的方法

抽象数据类型就是一个概念

列表 就是一个抽象数据类型,元组 也是,元组里面也有方法,它能存数据,也能对数据进行操作,int 也是抽象数据类型,float也是抽象数据类型

所以说,只要类里面有属性,能够数据存储;有方法,就能够对属性进行操作,这个东西就叫 抽象数据类型

比如,我现在给你一个列表,我想从最后一位“6”开始删除,而不是从“1”开始按顺序往后删除,那么我们就可以用列表里的一个pop()方法,所以说一个抽象数据类型里有好多操作方法可以进行对存储数据进行操作。
在这里插入图片描述
pop( ) 从最后一个开始移除,只提供pop()方法,把remove方法删掉,甚至有一些其他的功能不需要也删掉,实现一个符合要求的特殊的数据类型,还能够对数据进行一些我要求的一些操作

属性的目的是存储数据,方法的目的是操作属性,操作数据,对这些数据进行增、删、改、查
(列表里面提供一个remove可以从中间删)

属性是私有化的,不通过方法你访问不到

集合、列表list 就是一个线性表,就是数据排列像一条线,就是线性表,元组 也是线性表,矩阵 就不是线性表,因为矩阵是二维的,最终画完是一条线y=a*x+b就是线性表

属性:(包含两部分,一部分存储真正的数据,一部分存储下一个地址),一个属性不能存俩值,所以得两属性
1.data-存储数据
2.next-下一个节点的地址

方法增、删、改、查----> 删 和 插入比较方便,删除和插入需要移位,追加不需要移位
next:后继
pre:前驱

pre永远走的比next走的慢一步,next指向下一个位置,pre换上次next的位置


二、线性表(主要讲:链表)

简称 表,一个线性表是某类元素的一个集合,还记录着元素之间的一种顺序关系。

在程序中,经常需要将一组(通常是同为某个类型)数据元素作为整体管理和使用,需要创建这种元素组,用变量记录它们,传进传出函数等。

1、线性表的概念和表抽象数据类型

表可以看作一种抽象的(数学)概念,也可以作为一种抽象数据类型。

一个表中包含的元素个数称这个表的长度,显然,空表的长度为 0。

在一个非空的线性表里,存在着唯一的一个首元素和唯一的一个尾元素(或称末元素)。除了首元素之外,表中的每个元素e都有且仅有一个前驱元素;除了尾元素之外的每个元素都有且仅有一个后继元素

通俗来讲,什么叫线性表呢?

外观看起来像一条线,比如:列表list、元组tuple等,就是线性表

顺序表和链表的区别:

链表和列表不一样,它俩有好有坏:
链表(删除 和 插入 比较好)
列表(查看,比较快)
在这里插入图片描述

顺序表和链表由于存储结构上的差异,导致它们具有不同的特点,适用于不同的场景。通过系统的学习顺序。

虽然它俩同属于线性表,但
1.数据的存储结构有本质的不同

  • 顺序表存储数据,需预先申请一整块足够大的存储空间,然后将数据按照次序逐一存储,数据之间紧密贴合,不留一丝空隙
  • 链表的存储方式与顺序表截然相反,什么时候存储数据,就什么时候才申请存储空间,数据之间的逻辑关系依靠每个数据元素携带的指针维持

2.开辟空间方式不同:

  • 顺序表存储数据实行的是“一次开辟,永久使用”,即存储数据之前先开辟好足够的存储空间,空间一旦开辟,后期无法改变大小(使用动态数组的情况除外)
  • 而链表则不同,链表存储数据时,一次只开辟存储一个节点的物理空间,如果后期需要还可以再申请

因此,可见,若只从开辟空间方式的角度去看问题的话,当存储数据的个数无法提前确定,又或是物理空间使用紧张以至于无法一次性申请到足够大小的空间时,使用链表更有助于问题的解决。
在这里插入图片描述
3.空间利用率:

  • 顺序表的空间利用率显然比链表要高,因为链表在存储数据的时候,每次只申请一个节点的空间,且空间的位置是随机的。
    这种申请存储空间的方式会产生很多空间碎片,一定程序上造成了空间浪费。不仅如此,由于链表中每个数据元素都必须携带至少一个指针,因此,链表对所申请空间的利用率也没有顺序表高。
    在这里插入图片描述

2、顺序表的实现

Python的list:

列表中 元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)

[ 插入数据可重复,数据不唯一 ]

ListT=[1,"2",(3,4,5,6),[7,8,9],{"10":11},{12,13,14}]   # 列表可以存储数据类型:数字,字符,元组,列表,字典,set
print (ListT) 

ListT=

3、链接表

1.线性表的基本需要和链接表

实现线性表的另一种常用方式就是基于链接结

  • 3
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值