408数据结构复习笔记

第一章:绪论

关系:数据>数据元素>数据项

数据对象:性质相同的数据元素集合

数据结构:有特定关系的数据元素的集合

逻辑结构:线性与非线性

物理结构:顺序存储,链式存储,索引存储,散列存储

算法性质:有穷性,确定性,输入,输出可行性

算法设计:正确,可读,健壮,高效低空间

 

第二章:线性表(注意两种表的增删改查写法)

顺序表:静态分配,存储密度=1,随机存取,插入/删除时平均移动一半元素

链表:动态分配,存储密度<1,顺序存取,插入/删除时改动指针不需移动

 

第三章:栈与队列(注意栈/队列都是push时先++再赋值,pop时是先读再--)

栈先进后出,N个编号元素以某种顺序进栈,可以任意时刻出栈,则所获得编号元素排列数目N恰好是C(2N,N)/(N+1),按存储结构分顺序栈与链栈

队列先出先出,按存储结构分顺序栈与链栈

中序表达式求值,有可先求前/后缀表达式,再求值:

中缀:a+b*c-(d+e),按运算优先级变形:((a+(b*c))-(d+e))

前缀移动符号到对应括号左边:-( +(a *(bc)) +(de)),再去括号:-+a*bc+de

后缀移动符号到对应括号左边:((a(bc)* )+ (de)+ )-,再去括号:abc*+de+-

前缀求值,出现符号,就求后面两个数运算结果返回

后缀求值,数字压栈,出现符号就出栈两个数字运算,结果再入栈

补充后缀求值的C++算法:开后缀表达式字符串与符号栈,逐个符号判断,遇到数字直接入后缀,遇左括号直接打入符号栈,遇到右括号则把符号栈中至对应左括号之前的符号依次打入后缀式,遇到乘除号,把栈顶的乘除号打入后缀式,遇到加减号,把栈顶的四则运算符号打入后缀式,因为是最低优先级的,所以前面的四则运算必须要运算完(最后要么空栈,要么栈顶是左括号)

(解释一下为什么遇乘除号时,栈中加减号不能入后缀式,因为可以乘号后还有乘除,像1+2*3*4*5,+入栈,第一个*入栈,第二个*入栈前可把第一个*入后缀式,但是+不能入,因为可能后面还有乘,例中就是,4与5之间还有*)

 

第四-章:树

满二叉树:每层结点数达到最大值

完全二叉树:比满二叉树少了最底层,最右边的一些连续叶子结点

前中后序遍历:前中后是相对父结点而言,前序(父,左儿,右儿),中序(左儿,父,右儿),后序(左儿,右儿,父)

线索二叉树:有分前中后序线索二叉树,就是每个结点加两个标志位,但这个结点没有左儿时,左指针指向本结点前驱,没有右儿时右指针指向本结点后继

由前中序求后序:由前序字符判断右序式中的分界

森林与二叉树转换:见3-5转换方法

哈夫曼树:

构造:给定N个带权结点,先建有N棵单结点二叉树的森林,再构造新结点从森林中选两棵根结点权值最小的树作为新结点的左右子树,并将新结点权值置为左右子树上根结点的权值之和,从森林中删除刚选的两棵树,同时将新得到的树加入森林,重复建一删二直至只剩一棵树为止

特点:

1.每个初始结点最终都是叶结点,且权值越小的结点到根结点路径长度越大

2.共建N-1个双分支结点,因此总结点数是2N1

3.每次构造都选择2棵树作为新结点的孩子,因此哈夫曼树不存在度为1的结点

4.用N个叶子结点构造的哈夫曼树形态不唯1,但带权路径长度唯一

5.可设计出总长度最短的二进制前缀编码(左0右1)

二叉排序树:

增:插入关键字小于当前结点关键字就插入到左子树中,否则就右子树中,最后必插在叶子

删:叶结点直接删,只有单儿子直接提,有双儿用中序后继或前驱替代转变成删这个后继或前驱

改&查:按左子树<根<右子树寻找结点即可

平衡二叉树:左子树与右子树都是平衡二叉树且左子树和右子树的高度差的绝对值不超过1

平衡因子:结点左子树与右子树的高度差为该结点平衡因子。

最小不平衡子树:在插入路径上离插入结点最近的平衡因子的绝对值大于1的结点作为根的子树

参考二叉排序树,增加结点后如果不再平衡,需要找到最小不平衡子树进行调整(四种旋转)

完全二叉树性质:从上到下,从左到右依次编号1到N

若i<=floor(n/2),则结点i为分支结点,否则为叶子结点,也即最后一个分支结点的编号为floor(n/2)

叶子结点只可能在层次最大的两层上出现(若删除满二叉树中最底层、最右边的连续2个或以上的叶子结点,则倒数第二层将会出现叶子结点)

如果有度为1的结点,只可能有一个,且该结点只有左孩子而无右孩子

按层序编号后,一旦出现某结点(其编号为i)为叶子结点或只有左孩子,则编号大于i的结点均为叶子结点

若n为奇数,则每个分支结点都有左右儿,若N为偶数,则编号最大的分支结点(编号n/2)只有左儿没有右儿,其余分支结点左右都有

结点i所在层次(深度)为floor(log(2)i)+1

具有n个(n>0)结点的完全二叉树的高度为ceiling(log(2)(n+1))或floor(log(2)n)+1

 

第五章:图

最小生成树:

Prim:任取一点为树,不断取与这棵树相接的边中最短的一条加入

Kruskal:对所有边排序,依次选取最短边建树,需建立并查集防有环
最短路径:

Dijkstra:开始时点集只有起点,然后把与当前点集相连的点压入优先队列(带着到原点的距离来排序),取出队首的点压入点集并把与新点相连的剩余结点继续压入优先队列,如此循环

Floyd:暴力N^3,枚举每两个条边之间的中间点最短矩离

关键路径(拓扑排序):

边是活动,边权是时间,点是事件,VE是事件最早发生时间,VL是事件最迟发生时间

1拓扑排序

2求事件ve最早开始时间(拓扑排序就是为了求这个,代码中是顺便求的),求事件vl最迟开始时间(射向的点中最迟开始时间的最小值减去边权,vl(k)=vl(j)-<k,j>,汇点的最迟开始时间就是最早开始时间,以此为根源往前推)

3求活动的最迟发生时间(事件最迟发生时间减去以它为结束点的活动的持续时间)

  求活动的最早发生时间(就是射出的点的最早开始时间)

4活动的最早与最迟发时间相同就是关键路径,存入即可

 

第六章:查找2

顺序查找法:依次判断

折半查找法:对有序数组二分查找

B树:一棵M阶B树或为空树,或为满足下列特性的M叉树:

若根结点不是终端结点,则至少有两棵子树,至多有M棵子树

除根结点外的所有非叶结点至少有ceiling(m/2)棵子树,至多有M棵子树

所有的叶结点都出现在同一层次上,并且不带信息(可视为失败结点)

所有非叶结点的结构是编号,关键字及对应指针

B+树:

每个分支结点最多M棵子树

非叶根结点至少有两棵子树,其他每个分支结点至少有ceiling(m/2)棵子树

结点的子树个数与关键字个数相等!!!

所有叶结点包含全部关键字及指向相应记录的指针,而且叶结点中将关键字按大小顺序排列,并且相邻叶结点按大小顺序相互链接起来

所有分支结点(可视为索引的索引)中仅包含它的各个子结点(即下一级索引块)中关键字的最大值及指向其子结点的指针

散列表:建立关键字和存储地址之间的一种直接映射关系,把关键字映射成其对应地址的函数称为散列函数,记为Hash(key)

冲突:散列函数把两个或两个以上的不同关键字映射到同一地址

构造方法:除留余数法H(key)=key%p

冲突处理方法:

开放定址法:

发生冲突后第i次探测的散列地址为Hi=(H(key)+di)%m,M是表长,DI是增量序列

当di=1,2……m-1称线性探测法,冲突发生时顺序查看表中下一个单元,直到找出一个空闲单元或查遍全表。线性探测法易造成“聚集”现象。当di=1^2,-1^2,2^2,-2^2……k^2,-k^2,其中k<=m/2,m必须是可表示成4K+3的质数,称二次探测法

拉链法:

    把所有散列地址相同的记录存储在同一个线性链表中,这个线性链表由散散列地址唯一标识。拉链法适用于经常进行插入和删除的情况。

平均查找长度是查找过程中进行关键字的比较次数的平均值:求和PiCi

Pi是查找第i个数据元素概率,Ci是找到第i个数据元素所需的比较次数

 

第七章:排序

插入排序:

       直接插入:第i轮将数组第i个数顺序查找到前面已排序的[1,i-1]中正确位置并后移,其后的后移,时间N方,空间O1

       折半插入:第i轮将数组第i个数二分查找到前面已排序的[1,i-1]中正确位置并后移,其后的后移,时间N方,空间O1

       希尔插入:总序列分成若填下子序列分别直接插入,最后再全体直接插入

交换排序:

       冒泡排序:第i轮[1,n-i]每个数与其后相邻的数比较大者在后,每轮最大数会冒在最后,时间N方,空间O1

快速排序:选择一个枢轴元素(第一个),在完成一轮划分后,将等排序序列分割成两部分,左侧元素关键字小于等于枢轴元素关键字;右侧元素的关键字大于等于枢轴元素的关键字,再分别对两部分元素重复上述过程,直到整个序列有序,时间NLOGN,空间ON,每轮算法如下:

              1、i=1,j=n;j

2、j往前找到第一个小于a[i]的数,交换ij位的数

3、i往后找到第一个大于a[j]的数,交换ij位的数

4、循环2,3步,注意第2步的a[i]与第3步的a[j]每轮是一样的,故称枢轴

选择排序:

       简单选择:第i轮取[i,n]中最小者与第i位交换位置,每轮最小数会被选在最前,时间N方,空间O1

       堆排序:堆顶永远是最值,时间NLOGN空间O1 ,算法如下:

建堆:长为N的序列对应N个结点的完全二叉树,依次对以第floor(n/2),floor(n/2)-1……1个结点为根的子树调用堆的调整操作:若结点大于左右结点值就结束,否则与左右结点中较大值交换,并对发生交换的下一级进行调整操作

                     插入:新结点放在堆末,然后往上交换直至比其父亲小

                     删除:堆的最后一个元素代替堆顶元素并以他为根调用调整操作

归并排序:就是分治,分到子表长为1,然后两两归并,时间NLONG,空间N

基数排序:按十位数分成十分队列把原序列数打入,对每个序列中的数按个位数排序,最后全部序列整体排序就是结果

  • 15
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值