软件设计基础:2. 数据结构
数据结构是算法重要组成部分,本文是学习数据结构的笔记。
1.线性结构
1.1线性表
- 顺序表:就是连续的一串数据,物理上是连续的。
- 链表-单链表:物理上无序。一般情况下一个元素有两个信息,一个是本身的值,另一个是指针,指向下一个元素。
- 链表-双向链表:物理上无序。一般情况下一个元素有三个信息,一个是本身的值,另外是两个指针,分别指向上下两个元素。
- 链表-循环链表:其实分单链和双链两种循环链表,特点是头尾相连。
1.2队列与栈
- 队列:类似排队上厕所,先进先出
- 栈:类似躲防空洞,后进的先出,或者先进后出
1.3串
例如:string val = ""1234123456456789;
- 子串:val有三个子串,1234、123456、456789
- 广义表:例1:广义表((a,b),c,(d,e))中,(a,b)是一个元素,c是一个元素,(d,e)是一个元素,即长度为3。(a,b)和(d,e)算同样的一层,所以总层数为2,即深度为2。
1.4顺序表和链表存储
性能 | 顺序存储 | 链式存储 |
---|---|---|
存储密度 | =1,更优 | 1/2或者1/3,,即<1 |
容量分配 | 事先确定 | 动态变化,更优 |
查找运算 | 找个数,最快0,最慢n,平均O(n/2) | O(n/2) |
读取运算 | O(1),读下标就行 | O([n+1]/2) |
插入运算 | O(n/2),插一个剩下往后移 | O(1),拆链就行 |
删除运算 | O([n+1]/2) | O(1) |
2.数组与矩阵
2.1数组
- 一维数组地址计算:a[i],的存储地址M+i*len,M代表起始地址。
- 二维数组地址计算:实际上很简单,但是解释起来麻烦,我们看一个例子;
- 二维数组例题:二维数组A的每个元素是由10个字符组成的串,其行下标i=0,1,…,8,列下标j=1,2,…,10。若A按行先存储,元素A[8,5]的起始地址与当A按列先存储时的元素( )的起始地址相同。
- 答案解析:设每个字符占一个字节。LOC(A[8][5]) = M+((8-0)*10+(5-1)) = 84;那么((?-0)+(?-1)*9)=84? 答案:A[3,10]
- 二维数组B[0…m-1 ,0…n-1] 最后一个数据为B[m][n],是一个m行 n列的数组,注意数列是反的B[0…m-1 ,0…n-1] ,。
- 以行优先,就是按行存储,和我们平时阅读书本的顺序差不多。如LOC(b[2][4])= LOC (b[0][0])+(2×n+4)×每个元素所占存储单元
- 以列优先,就是按行存储。如LOC(b[2][4])= LOC (b[0][0])+(2+4*m)×每个元素所占存储单元
2.2矩阵
- 矩阵加/减法,行列一致,对位相加
- 矩阵乘法,两个矩阵A和B相乘,需要满足A的列数等于B的行数。然后A矩阵的行元素乘以每一列然后相加作为新矩阵的行元素。
- 上三角矩阵:(2n-i+1)*i/2+j。
- 下三角矩阵:(n+1)*i/2+j。两者就是2n-i和n的区别
- 实际运用:注意例题中数组M的下标从1开始,不是默认的0,正常都是0开始
3树
3.1树与二叉树的特性
- 结点的度:当前结点的孩子结点的个数。
- 树的度:树中所有结点的度最大值。
- 叶子结点:度为0的结点。
- 内部节点:度不为0的结点。
- 父结点:
- 子结点:
- 兄弟结点:
- 层次:根结点为第一层,之后层数依次加1。
二叉树特性
-
性质一:i层最大结点数为2i-1。1层,21-1=1个结点;3层,23-1=4个节点。
-
性质二:对于一棵深度为k的二叉树,可以具有的最大结点数量为:1+2+4+8…。即20+21+…。即2k-1。节点的边数为E=n - 1,因为每个节点都有一个边和上边相连,除了根节点。
-
性质三:叶子节点与度为2的节点的关系式n0=n2+1
-
性质四:一棵具有n个结点的完全二叉树深度为 k=⌊log2n⌋+1
-
性质五:n个结点,其左孩子为2i,右孩子为2i + 1,如果i = 1,那么此结点为二叉树的根结点,如果i > 1,那么其父结点就是 ⌊i/2⌋,比如第3个结点的父结点为第1个节点,也就是根结点。如果2i > n,则结点i没有左孩子,如果2i + 1 > n,则结点i没有右孩子。
3.2二叉树的遍历
①先序遍历:采用DLR(根左右,根-先左-右),得到的结果是:1 24578 36。
②中序遍历:采用LDR(左根右,满足型),得到的结果是:42785 1 36。
③后序遍历:采用LRD(左右根,满足型),得到的结果是:48752 63 1。
④层次遍历:依次获取每层的结点,得到的结果是:1 23 456 7 8。
要想唯一确定一棵二叉树,必须要有中序遍历的序列结果!!!
3.3反向构造二叉树
3.3二叉排序树?
是一种特殊的树,左孩子大于根,右孩子小于跟。左大右小。
中序遍历的遍历结果是有序的
3.4最优二叉树(哈夫曼树)
- 树的路径长度:根到每个子节点的长度之和
- 权:每个节点上带有权值
- 带权路径长度:权值 × 根到叶子节点长度
- 树的带权路径长度:每个节点的权值 × 路径长度之和
- 构造过程:1.先选取权值最小的一组进行构造;2.构造完成之后,删除这对已经构造的权值,生成一个新的权值,为这两者之和;3.重复上诉步骤,进行选择一对最小权值进行构造
对应c的编码111,a的编码0,d的编码110,e的编码101,第一空选择A选项。
压缩前,若要表示5个不同的字符,用二进制编码至少需要3位二进制,即每位字符占据空间3bit,平均字符长度为:
3×40%+3×10%+3×20%+3×16%+3×14%=3;
压缩后,这5个字符的编码长度分别为1、3、3、3、3,平均编码长度为:
1×40%+3×10%+3×20%+3×16%+3×14%=2.2;
压缩比为(3-2.2)/3=27%。
3.5其他特殊二叉树?
- 平衡二叉树:任意节点的左右子树深度相差不超过1;
- 线索二叉树
3.6树转二叉树
中间砍掉,然后用一个折线连起来
4.图
4.1图的定义与存储
4.1.1 定义
- 完全图:每队顶点之间都有一条边相连(无向图是一条边,有向图是两条边)
- 连通图:任意两个顶点之间都有一个路径相连
4.1.2存储
- 邻接表:时间复杂度为O(n2)。根据邻接表的定义,一个顶点的表结点个数为其邻接顶点的个数,顶点2有2个邻接顶点,顶点3有2个邻接顶点。
- 邻接矩阵:时间复杂度为O(n+e)。根据邻接矩阵的定义,行列数都为结点个数,结点数为5,因此邻接矩阵行列数均为5,即5×5的矩阵。
4.2图的遍历
- 深度遍历,类似先序遍历,根左右
- 广度遍历
4.3拓扑排序
用有向边表示活动之间开始的先后顺序
4.4最小生成树与与最短路径问题
- 克鲁斯卡尔算法
- 普利姆算法
本文参考了https://blog.csdn.net/qq_38628970/article/details/129367795博客的内容,感谢JosieBook的大作