数组类型 | 存储地址计算 |
---|---|
一维数组a[n] | a[i] 的存储地址为:a + i * len |
二维数组a[m][n] | a[i][j] 的存储地址(按行存储):a + (i * n + j) * len a[i][j] 的存储地址(按列存储):a + (j * m + i) * len |
一个矩阵中存储的大量元素是0
稀疏矩阵 | 示意图 | 要点 |
---|---|---|
上三角矩阵 | ![]() | 在矩阵中下标分别为 i 和 j 的元素,对应的一维数组的下标计算公式为: |
下三角矩阵 | ![]() | 在矩阵中下标分别为 i 和 j 的元素,对应的一维数组的下标计算公式为: |
考试中常用代入法:
数据结构是相互之间存在一种或多种特定关系的数据元素的集合,是一种数据组织、管理和存储的格式。
逻辑结构:线性结构、非线性结构(树、图)
线性结构的基本表现,分顺序存储结构(顺序表)和链式存储结构(链表)
顺序存储与链式存储对比:
元素按照a、b、c的次序进入栈,写出所有可能的出栈序列:
- a进,a出,b进,b出,c进,c出,顺序:a,b,c
- a进,b进,b出,a出,c进,c出,顺序:b,a,c
- a进,b进,c进,c出,b出,a出,顺序:c,b,a
- a进,a出,b进,c进,c出,b出,顺序:a,c,b
- a进,b进,b出,c进,c出,a出,顺序:b,c,a
广义表是由n个表元素组成的有限序列,是线性表的推广
通常用递归的形式进行定义,记作:
LS是表名,是表元素,可以是表(称作子表),也可以是数据元素(称作原子),n是广义表的长度(最外层包含的元素个数)
n=0的广义表为空表,递归定义的重数是广义表的深度,简单来说就是定义中所含括号的重数(原子的深度为0,空表的深度为1),也就是嵌套层数
基本运算:取表头head(Ls)和取表尾tail(Ls),
若有:LS1=(a, (b, c), (d, e))
,则 head(LS1) = a
,tail(LS1) = ((b, c), (d, e))
几种特殊的二叉树:
二叉树的重要特性:
按层进行遍历:1,2,3,4,5,6,7,8
先访问根结点,再访问左子树结点,再访问右子树结点:1,2,4,5,7,8,3,6
先访问左子树结点,再访问根结点,再访问右子树结点:4,2,7,8,5,1,3,6
先访问左子树结点,再访问右子树结点,再访问根结点:4,8,7,5,2,6,3,1
知道一定的二叉树的遍历序列,反向推出二叉树的情况
基本原则:
一类比较特殊的二叉树
插入结点:
删除结点:
用于哈夫曼编码,让原始信息的编码长度变得更短,属于无损压缩
权*路径长度
构造一个哈夫曼树要达到的效果是树的带权路径长度最短
目的:将空闲的结点分支利用起来,方便遍历,左子树结点指向对应遍历顺序的前序结点,右子树结点指向对应遍历顺序的后序结点
平衡度:左子树深度-右子树深度,所有叶子结点的平衡度都是0
用一个n阶方阵R来存放图中各结点的关联信息
对于无向图,邻接矩阵为了节省存储空间,可以只存上三角或下三角
首先把每个顶点的邻接顶点用链表示出来,然后用一个一维数组来顺序存储上面每个链表的头指针
类似于树的前序遍历
V1,V2,V4,V8,V5,V3,V6,V7
V1,V2,V3,V4,V5,V6,V7,V8
用一个序列来表达一个图中哪些序列可以先执行,哪些序列可以后执行
把有向边表示活动之间开始的先后关系,这种有向图称为用顶点表示活动网络,简称AOV网络
把图中的边只留下若干条权值最小的,能够把所有顶点连接起来,成为一棵树
基本思想:从任意一个结点出发,将其定为红点集,其它为蓝点集,选出一条从红点集到蓝点集最短距离的边,并将连接到的点纳入红点集,重复进行
首先确定选几条边,然后从最短的边开始选起,但不能选边之后成环
时间复杂度:程序运行从开始到结束所需要的时间
空间复杂度:一个算法在运行过程中临时占用存储空间大小的度量
一般来说,算法中原操作重复执行的次数是规模n的某个函数,由于许多情况下要精确计算是困难的,因此引入了渐进时间复杂度在数量上估计一个算法的执行时间
如果存在两个常数和,对于所有的,当时有,则有。也就是说,随着的增大,渐进地不大于。例如,一个程序的实际执行时间为,则
常见的对算法执行所需时间的度量:
多用于树中
从头到尾进行比较,若存在则成功
查找成功时,顺序查找的平均查找长度为(等概率情况下):
时间复杂度为
前提:序列是有序的
mid为小数是向下取整
二分查找在查找成功时关键字的比较次数最多为次
二分查找的时间复杂度为
基本思想:已知关键字集合U,最大关键字为m,设计一个函数Hash,它以关键字为自变量,关键字的存储地址为因变量,将关键字映射到一个有限的、地址连续的区间T[0..n-1](n<<m)中,这个区间就称为散列表,散列查找中使用的转换函数称为散列函数
散列表冲突的解决方法:线性探测法、伪随机数法
稳定排序:相同的元素在排序后的相对位置不变
内排序:在内存中的排序
当插入第i个记录时,R1,R2,...,Ri-1已经排好序,因此Ri与他们进行比较,找到合适的位置插入,速度很慢
希尔(Shell)排序:先取一个小于n的整数作为第一个增量,把文件的全部记录分成个组。所有距离为的倍数的记录放在同一个组中。先在各组内进行直接插入排序,然后去第二个增量重复上述的分组和排序,直至所取的增量,即所有记录放在同一组中进行直接插入排序为止。该方法实质上是一种分组插入方法,比直接插入排序快
首先在所有记录中选出最小的记录,把它与第1个记录交换,接下来从剩下的纪录中选出最小的与第2个记录交换,以此类推
所有排序算法中最复杂的算法
堆:
先将序列建立堆,然后输出堆顶元素,再将剩余元素建立堆,输出堆顶元素
初建堆的过程:从最后一个非叶子结点开始调整,与其子结点比较大小
排序过程:
效率比直接选择排序高,应用场景在取前n个排序后元素
通过相邻元素之间的比较和交换,将排序码较小的元素逐渐从底部移到顶部
采用分治法,基本思想是将原问题分解成若干个规模更小但结构与原问题相似的子问题,递归地解决子问题
把两个或两个以上有序子表合并成一个新的有序表
若只合并两个,称为二路合并
合并过程:比较A[i]
和A[j]
的排序码大小,若A[i]
的排序码小于等于A[j]
的排序码,则将第一个有序表中的元素A[i]
复制到R[k]
中,并令i和k分别加1,如此循环下去,知道其中一个有序表比较和复制完,然后再将另一个有序表的剩余元素复制到R中
借助多关键字排序思想对但逻辑关键字进行排序的方法。适合于元素很多而关键字较少的序列
基数的选择和关键字的分解是根据关键字的类型来决定的,例如关键字是十进制数,则按个位、十位、百位来分解
本文作者:Morales
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 License 许可协议。转载请注明出处!