python学习笔记--数据结构

算法分为顺序结构、选择结构、循环结构,可以使用N-S流程图表示算法。

什么是数据结构?

数据结构是用于存储和组织数据的代码结构,使修改、导航和访问信息变得更加容易。数据结构决定了如何收集数据、我们可以实现的功能以及数据之间的关系。 数据结构几乎用于计算机科学和编程的所有领域,从操作系统到前端开发,再到机器学习。 数据结构有助于:

  • 管理和利用大型数据集
  • 从数据库中快速搜索特定数据
  • 在数据点之间建立清晰的分层或关系连接
  • 简化并加快数据处理

数据结构是高效、真实解决问题的重要构建模块。数据结构是经过验证和优化的工具,为您提供了一个简单的框架来组织您的程序。毕竟,你没有必要每次都重新制作轮子 (或结构)。

每个数据结构都有一个最适合解决的任务或情况。Python有4个内置的数据结构、列表、字典、元组和集合。这些内置数据结构带有默认方法和幕后优化,使其易于使用。

  • List:类似数组的结构,允许将一组相同类型的可变对象保存为变量。
  • 元组:元组是不可变的列表,意味着元素不能被更改。它是用圆括号声明的,而不是方括号。
  • Set:集合是无序的集合,这意味着元素是没有索引的,并且没有集合序列。它们用花括号声明。
  • 字典(dict):类似于其他语言中的hashmap或哈希表,字典是键/值对的集合。用空花括号初始化空字典,并用冒号分隔的键和值填充。所有键都是唯一的、不可变的对象。
  • 列表中删除偶数整数
  • 合并两个排序列表
  • 在列表中找到最小值
  • 最大总和子列表
  • 打印所有元素

线性表

线性表:各元素之间都是一对一的关系,除第一个和最后一个元素外,其他数据元素都是首尾相连的。

1.线性结构的特征

线性表是一种线性结构具有以下特征:

集合中必须存在唯一的第一元素和最后元素

除最后元素外,均有唯一的后继元素。除第一个元素外,均有唯一的前驱元素。

2.线性表的结构特点

均匀性:同一线性表的数据元素和长度必须相同。

有序性

顺序表

是通过一组地址连续的存储单元对线性表中的数据进行存储的,相邻的两个元素在物理位置上也是相连的。

第一个元素存储在LOC(1),那么第i个元素就存储在LOC(1)+(i-1)*sizeof(ElemType)。其中sizeof(ElemType)代表每个元素所占的空间。

插入、清空、删除、长度、检查是否已满、获取表元、按值查找。

shunxubiao.py

链表

链式存储结构不需要逻辑上相邻的两个数据元素在物理结构上也相邻,在插入和删除的时候不需要再移动元素,因此提高了运行效率。

单链表danlianbiao.py

循环链表:单向循环链表为单向链表的变种,链表的最后一个next指向链表头,新增一个循环。xunhuanlianbiao.py

双向链表、静态链表

队列

队列只能在尾部添加元素,头部删除元素。适合先进先出数据的存储。

队列分类

python中依赖queue模块实现队列

队列的方法

四种队列的操作:duilie.py

基于列表实现的优先队列:youdui.py

后进先出,允许在同一端执行插入和删除操作,允许操作的一端称为栈顶,不允许的一端称为栈底。入栈(push),出栈(pop)。

入栈:

top》n,显示溢出。

top=top+1,指针加1,指向进栈地址。

s(top)=x,结束操作。

出栈:

top《0,则输出溢出信息

不为空x=s(top),把出栈后的元素赋给x

设置top=top-1,结束操作,将栈指针减一,指向栈顶。

顺序栈:shunxu.py

栈底位置不变,栈顶用整型变量top作为栈顶指针。

堆队列

堆队列是一个二叉树,它的父节点的值小于或等于它的任何子节点的值。根元素值最小。

dui1.py

二叉堆实现优先队列的方法,二叉堆有两种,键值最小的排在前边称为最小堆,键值最大的排在前边称为最大堆。brackets.py

  • 树是数据元素之间具有层次关系的非线性结构,是由 � 个结点构成的有限集合,结点数为 0 的树叫空树。
  • 树必须满足以下条件
  1. 有且仅有一个被称为根的结点
  2. 其余结点可分为 � 个互不相交的有限集合,每个集合又构成一棵树,叫根结点的子树
  • 与线性结构不同,树中的数据元素具有一对多的逻辑关系,除根结点以外,每个数据元素可以有多个后继但有且仅有一个前驱,反映了数据元素之间的层次关系。
  • 树是递归定义的。

  • 结点是树的基本单位,若干个结点组成一棵子树,若干棵互不相交的子树组成一棵树。

树的术语

  • 结点:树的结点就是构成树的数据元素,就是其他数据结构中存储的数据项,在树形表示法中用圆圈表示
  • 结点的路径:结点的路径是指从根结点到该结点所经过结点的顺序排列
  • 路径的长度:路径的长度指的是路径中包含的分支数
  • 结点的度:结点的度指的是结点拥有的子树的数目
  • 树的度:树的度指的是树中所有结点的度的最大值
  • 叶结点:叶结点是树中度为 0 的结点,也叫终端结点
  • 分支结点:分支结点是树中度不为 0 的结点,也叫非终端结点
  • 子结点:子结点是指结点的子树的根结点,也叫孩子结点
  • 父结点:具有子结点的结点叫该子结点的父结点,也叫双亲结点
  • 子孙结点:子孙结点是指结点的子树中的任意结点
  • 祖先结点:祖先结点是指结点的路径中除自身之外的所有结点
  • 兄弟结点:兄弟结点是指和结点具有同一父结点的结点
  • 结点的层次:树中根结点的层次为 0,其他结点的层次是父结点的层次加 1
  • 树的深度:树的深度是指树中所有结点的层次数的最大值加 1
  • 有序树:有序树是指树的各结点的所有子树具有次序关系,不可以改变位置
  • 无序树:无序树是指树的各结点的所有子树之间无次序关系,可以改变位置
  • 森林:森林是由多个互不相交的树构成的集合。给森林加上一个根结点就变成一棵树,将树的根结点删除就变成森林

二叉树

普通二叉树

  • 二叉树是特殊的有序树,它也是由 n个结点构成的有限集合。当 n=0 时称为空二叉树。二叉树的每个结点最多只有两棵子树,子树也为二叉树,互不相交且有左右之分,分别称为左二叉树和右二叉树。

  • 二叉树也是递归定义的,在树中定义的度、层次等术语同样也适用于二叉树。

满二叉树

满二叉树是特殊的二叉树,它要求除叶结点外的其他结点都具有两棵子树,并且所有的叶结点都在同一层上。

完全二叉树

只有最下面的两层节点的度小于2,并且最下面一层的节点都集中在该层最左边的若干位置的二叉树中。

二叉树的性质

【数据结构】之二叉树的5个性质_二叉树的性质-优快云博客

性质五

二叉树的存储结构

1. 顺序存储

  • 二叉树的顺序存储结构是指将二叉树的各个结点存放在一组地址连续的存储单元中,所有结点按结点序号进行顺序存储。因为二叉树为非线性结构,所以必须先将二叉树的结点排成线性序列再进行存储,实际上是对二叉树先进行一次层次遍历。二叉树的各结点间的逻辑关系由结点在线性序列中的相对位置确定。
  • 可以利用性质5将二叉树的结点排成线性序列,节点i,的左子节点是2i,右子节点是2i-1。将结点存放在下标为对应编号的数组元素中。为了存储非完全二叉树,需要在树中添加虚结点使其成为完全二叉树后再进行存储,这样会造成存储空间的浪费。

2. 链式存储

二叉树的链式存储结构是指将二叉树的各个结点随机存放在存储空间中,二叉树的各结点间的逻辑关系由指针确定。每个结点至少要有两条链分别连接左、右孩子结点才能表达二叉树的层次关系。根据指针域个数的不同,二叉树的链式存储结构又分为以下两种:

二叉链式存储结构

  • 二叉树的每个结点设置两个指针域和一个数据域。数据域中存放结点的值,指针域中存放左、右孩子结点的存储地址。
  • 采用二叉链表存储二叉树,每个结点只存储了到其孩子结点的单向关系,没有存储到其父结点的关系,因此要获得父结点将花费较多的时间,需要从根结点开始在二叉树中进行查找,所花费的时间是遍历部分二叉树的时间,且与查找结点所处的位置有关。

三叉链式存储结构

  • 二叉树的每个结点设置三个指针域和一个数据域。数据域中存放结点的值,指针域中存放左、右孩子结点和父结点的存储地址。

两种链式存储结构各有优缺点,二叉链式存储结构空间利用率高,而三叉链式存储结构既便于查找孩子结点,又便于查找父结点。在实际应用中,二叉链式存储结构更加常用。

使用嵌套列表表示树:qian.py

把二叉树的任何子节点当作二叉树:jie.py

实现二叉搜索树查找操作:chashu.py

删除节点:节点S的左右孩子都不为空,将其右子树找到后继节点,将后继节点的值赋值为S,然后删除这个节点就可以,如果S的左孩子右孩子为空,就能够直接删除这个节点 。

在删除的时候需要考虑三种情况:没有孩子,有一个孩子,有两个孩子         

首先需要用_get()方法找到这个值所在的节点

二叉搜索树:左子树不为空时,左子树的节点值小于根节点。右子树不为空时,右子树的节点值大于根节点。

二叉树的查找、获取和删除:erwan.py

二叉树的遍历

N(Node)、L(Nodeleft)、R(NodeRight)

NLR、LNR、LRN、NRL、RNL、RLN

二叉树的遍历是指沿着某条搜索路径访问二叉树的结点,每个结点被访问的次数有且仅有一次。

二叉树通常可划分为三个部分,即根结点、左子树和右子树。根据三个部分的访问顺序不同,可将二叉树的遍历方法分为以下几种。

  • 前序遍历NLR:先访问根结点,再前序遍历左子树,最后前序遍历右子树。
  • 中序遍历LNR:先中序遍历左子树,再访问根结点,最后中序遍历右子树。
  • 后序遍历 LRN:先后序遍历左子树,再后序遍历右子树,最后访问根结点。
  • 层次遍历:自上而下、从左到右依次访问每层的结点。

二叉树遍历操作的递归算法结构简洁,易于实现,但是在时间上开销较大,运行效率较低,为了解决这一问题,可以将递归算法转换为非递归算法,转换方式有以下两种:

  • 使用临时遍历保存中间结果,用循环结构代替递归过程
  • 利用栈保存中间结果

二叉树遍历操作实现的非递归算法利用栈结构通过回溯访问二叉树的每个结点。

遍历:biancha.py

线索二叉树

线索二叉树(前中后序线索化/遍历/画线索)_中序线索二叉树怎么画-优快云博客

获取二叉树的高度、宽度和深度,实现二叉树的前序、后序和中序遍历,遍历的非递归实现:gaoshen.py

  • 高度:从根节点到最远叶子节点的最长路径上的节点数。
  • 深度:某个节点所在的层数(从根节点开始算起)。
  • 宽度:某一层上节点的最大数量。

霍夫曼树(哈夫曼树、最优二叉树)

霍夫曼编码是一种有效的无损压缩方法,广泛应用于数据压缩和传输领域。其核心思想是利用字符出现频率构建最优二叉树,为高频字符分配较短的编码,实现数据的高效压缩。在实际应用中,霍夫曼编码不仅限于文本数据的压缩,还可以用于图像、视频等多媒体数据的压缩。

Python实战开发及案例分析(29)—— 霍夫曼树_python arithmeticcoding-优快云博客

huo.py

二、常用算法思想

2.1枚举算法思想

2.2递归算法思想

调动自身解决问题

斐波那契数列计算、阶乘问题

2.3分治算法思想

将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。只要求出子问题的解,就可得到原问题的解。

求顺序表中最大的值、判断某个元素是否在列表中、找出一组序列中第k小的元素

2.4贪心算法思想

思路:

1.建立数学模型描述问题

2.把求解的问题分成若干子问题

3.对每一个子问题求解,得到子问题的局部最优解

4.把子问题的局部最优解合并成原来问题的一个解。

找零问题:从最大的面额开始找,然后动态减少需要找零的数量

加油问题:加油站之间的单个距离不能超过油箱总量,在加油站个数内累加距离,当距离大于邮箱总量时累加距离清零、加油次数加一。这样实现了加一次油后尽量多跑距离的贪心思想

2.5试探算法

先选择某一种可能的情况进行试探,在试探过程中,一旦发现此选择的假设是错误的,就退回一步重新选择,继续向前试探,如此反复进行,直到证明解或者无解。

八皇后问题:要求在 8 × 8 的棋盘上摆放8个皇后,使”皇后“们不能互相攻击 ,当任意两个皇后都不处于同一行、同一列或同一条斜线上时就不会相互攻击,即为目标解。

第一层循环:k,从第0行开始,在不超过8行内遍历。

第二层循环:i,不冲突就移到下一行,定义一个冲突函数,冲突就在i内循环找到合适的位置。

迷宫问题

在八个方向中循环八次寻找方向,然后更新坐标,将新坐标放入冲突检测函数,入如果不冲突就标记这个位子已经走过并且从这个位置开始重新开始新的方向的循环。

2.6迭代算法

不断用变量的旧值推测新值

如何计算时间复杂度和空间复杂度

保姆级教学!彻底学会时间复杂度和空间复杂度 - 知乎 (zhihu.com)

时间复杂度--步长

空间复杂度--数据量

参考说明

1.张玲玲《python算法详解》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值