小杰数据结构(one day)——心若安,便是晴天;心若乱,便是阴天。
1.数据结构
计算机存储、组织数据的方式;
有特定关系的数据元素集合;
研究数据的逻辑结构、物理结构(真实存在)和对应的算法;
新结构仍保持原结构类型;
选择更高的运行或存储效率的数据结构。
逻辑结构——面向问题
物理结构面向计算机
基本目标是将数据及其逻辑关系存储到计算机的内存中
(1)基本概念
数据——数据对象——数据元素(节点-链表中常出现)-整体处理——数据项(数据最小单位)
(2)逻辑结构
1.集合结构
2.线性结构
3.树状结构(层次结构)
4.图形结构(网状结构)
(3)物理结构
①顺序存储结构
把数据元素/节点存放在地址连续的存储单元里
1.内存连续
2.相对于链式存储结构每个元素占用空间少
②链式存储结构
把数据元素/节点存放在任意的内存空间内,通过指针域来表示、连接
1.内存不连续
2.通过指针连接
③索引存储结构
存储数据同时,建立一个附加索引表(如通讯录)
1.索引速度快
2.多了一张索引表,占用内存多
3.删除数据文件时需及时更改索引表
④散列存储结构
构造相应散列函数,由散列函数值来确定 数据元素/节点 存放的地址
1.存时需按对应关系存
2.取时也按对应关系取
2.算法
(1)概念
软件 = 程序 + 文档
程序 = 数据结构 + 算法
软件 = 数据结构 + 算法 + 文档
算法 = 对结点集合的运算和操作 + 控制结构
软件、程序、算法——逐层包含关系
算法用来描述特定问题的求解步骤,指令有限序列,每个指令代表一个及以上操作
(2)五大特征
1.有穷性:
算法必须在有穷时间内完成
2.确切性:
指令必须有确切含义,不可有二义性。为True或False
3.可行性:
算法可行,算法中描述的操作都可实现
4.输入性:
可输入,以刻画对象的初始情况
5.输出性:
必须有一个或多个输出
(3)描述
算法的描述样式多样化,常用有四种。
1.自然语言描述法:
最简单的描述法
优点:简单、便于理解
缺点:不够严谨、易产生歧义。
2.算法框图法:
使用算法描述工具描述算法(如程序流程图)
特点:便于理解交流、简洁明了
3.伪代码语言描述法:
介于高级程序设计语言与自然语言之间
忽略了一些严格的语法规则与描述细节
比高级程序设计语言更容易描述和被人所理解
4.高级程序设计语言描述法:
可在计算机中执行的程序描述算法
优点:不用转换,可直接编译执行
缺点:比较难理解
所谓“程序”是指对所要解决问题的各个对象和处理规则的描述,或者说是数据结构和算法的描述,因此有人说“数据结构+算法 = 程序”。
程序可以不满足算法的有穷性(如,操作系统)
(4)标准
衡量一个算法的四个标准:
1.正确性:
能够正常运行,且得到正确答案
2.可读性:
便于阅读、理解和交流
3.健壮性:
当输入不合法时,算法能做出相关处理。
4.时间效率高与、低存储量需求:
执行时间少,耗内存少
(5)时间复杂度
一个算法的复杂性分析主要是对算法效率的分析,运行速度的时间效率,以及其运行时所需要占用的空间大小。
算法的时间复杂度是一个函数,它定性描述该算法的运行时间,时间复杂度常用 O 表述。
①概念
要想计算时间复杂度首先得找到该算法中的循环,算法中循环执行的次数就是算法的时间复杂度。
函数表达式:
T(n) = O(f(n))
T(n) 问题规模的时间函数
n 代表的是问题的规模 输入数据量的大小
O 时间数量级
f(n) 算法中可执行语句重复执行的次数
由此可得计算时间复杂度的一般规律(大O表示法),如:N*N+N+10
- 如果有常数项将其置为
1
。N*N+N+1
- 去除表达式中所有加法常数。
N*N+N
- 修改的表达式中 只保留最高阶项,因为只有它才会对最终结果产生影响。
N*N
- 如果最高阶项系数存在且不是
1
,则将其系数变为1
,得到最后的表达式。N*N
计算冒泡排序的时间复杂度:
Sn = [n*(a1+a2)]/2
3.顺序表
每种结构都有存在的意义
线性表的特点:一对一,每个节点最多一个前驱和一个后继,首尾节点特殊:首节点无前驱,尾节点无后继。
逻辑结构:线性结构
物理结构:顺序存储结构
def show(buf: list[int]):
遍历列表中的有效元素
last:
始终标记列表中最后一个有效元素下标
用global修饰
例:
练习:自己实现insert()思想
列表:buf = [1, 996, 520, 4, 5]
要求:第三个位置插入一个元素
def insert(buf, index, data):''':param buf:列表的首地址:param index:插入的位置:param data:给列表中插入的数据:return:'''for i in range(len(buf) - 1, index, -1):# 防止越界buf[i] = buf[i - 1]buf[index] = datadef show(buf):for i in range(len(buf)):print("buf[%s] = %s" % (i, buf[i]))if __name__ == '__main__':buf = [1, 520, 996, 4, 5]show(buf)insert(buf, 3, 888)show(buf)
last版本:
# 始终标记列表中最后一个有效元素的下标
last = 4def insert(buf, index, data):''':param buf:列表的首地址:param index:插入的位置:param data:给列表中插入的数据:return:'''global lastfor i in range(last, index - 1, -1): # last 0 index = 5 ;index + 1# 防止越界buf[i + 1] = buf[i]buf[index] = datalast = last + 1def show(buf):for i in range(last + 1):print("buf[%s] = %s" % (i, buf[i]))if __name__ == '__main__':buf = [1, 520, 996, 4, 5] + [0] * 16show(buf)insert(buf, 3, 888)show(buf)