1、计算机考研之终极笔记数据结构篇第一章 绪论1.1 时间复杂度的求法(一) 循环主体中的变量参与循环条件的判断a) 找出基本操作b) 设基本操作执行次数为T(n),根据初始条件和基本操作语句确定变量与次数的关系式c) 带回循环条件,求出T(n),确定O(n)(二) 循环主体中的变量与循环条件无关(1) 递归程序a) 确定递推关系(注意这里确定的是基本操作次数的递推关系)b) 推出递推关系与执行次数的表达式c) 令低级递推关系中的次数为常数(0或1),整理式子d) 推导出T(n)(2) 非递归程序 等比、等差数列求和1.2 实例王道单科P8,综合第二题1) 归类:循环主体中的变量参与循环条件的判断
2、基本操作:i+(注意不是k参与循环条件的判断)初始条件i=1,执行一次i加一,值为2;执行第二次,i再加一,值为3;执行T(n)次,i的值为T(n)+1;带回循环变量:in推出:T(n)=n-1 所以T(n)=O(n)3) 归类:循环主体中的变量与循环条件无关,非递归程序T(n)= 1=O(n3)4) 归类:循环主体中的变量与循环条件无关,非递归程序T(n)=M*N=O(M*N) 综合题第一题归类:循环主体中的变量与循环条件无关,递归程序递推关系已给,题中没给的要自己推出来T(n)=2T(n/2)+n(注意:这里的n,2等都是执行次数,不是变量的值)T(n/2)=2T(n/2*2)+n/2 把
3、带回得到T(n)=2*2*T(n/2*2)+2*n令T(n/2*2)中令n/2*2=1,解出n=2*2,2=Log2 nT(n)=n*T(1)+n*Log2 n = n+n*Log2 n = O(n*Log2 n) P7 第4题归类:循环主体中的变量参与循环条件的判断基本操作:x=x*2初始条件:x=2,执行一次后x=2*2,执行两次后x=2*2*2,执行T(n)次后,x=2T(n)带回循环变量:2T(n)=n/2T(n)= Log2(n) 1 = O(Log2(n) 第5题归类:循环主体中的变量与循环条件无关,递归程序基本操作:n*fact(n-1)递推关系:T(n)=1+T(n-1)(这里
4、1为上面的基本操作执行了一次)T(n-1)=1+T(n-2),代入上式得到:T(n)=1+1+T(n-2)令T(n-2)中n-2=0,则2=n原式整理为:T(n)=n+T(0)(这里表示的是次数的变化,即我每次减一,前面就加一,减到n时,前面也加到n)T(n)=n =O(n)第二章 线性表、栈、队列 2.1各种链表特殊操作的时间复杂度DS 复杂度 操作删除最后元素删除第一个元素在最后插入元素在最前插入元素单链表O(n)O(1)O(n)O(1)循环单链表(头指针)O(n)O(1)O(n)O(1)循环单链表(尾指针)O(n)O(1)O(1)O(1)双链表(头指针)O(n)O(1)O(n)O(1)双
5、链表(尾指针)O(1)O(n)O(1)O(n)双链表(头、尾指针)O(1)O(1)O(1)O(1)循环双链表O(1)O(1)O(1)O(1) 注意:若题中选项出现多个时间复杂度合适选项,选择修改指针最少的。 2.2链表的指针修改原则不断链原则 先定义一下指针(个人定义) 主链接性指针通过已知指针(头指针或尾指针)和该指针可以链接操作所有参与元素,即该指针一断,元素失去控制(断链); 非主链接性指针断开后不影响元素链接操作;(1) 对只有主链接性指针的链表操作步骤a) 建立新的主链接性指针b) 修改旧主链接性指针(2) 既有主链接性指针又有非主连接性指针a) 修改非主链接性指针b) 建立新的主链
6、接性指针c) 修改旧主链接性指针 2.3 链表算法设计 常用方法:头插法;尾插法;双指针;多指针(1) 删除 删除一个链表元素时,能同步找到它的直接前驱是最高效的,而如何实现同步直接影响算法的复杂程度(2) 建表 头插法;尾插法;双指针,各有各的特点,自己总结吧(3) 查找这几次考的都是通过双指针的距离查找元素位置(4) 排序 对无序链表排序,在空间复杂度为O(1)的条件下,时间复杂度最佳为O(n2)若算法设计是对当前排序的元素操作,则总体复杂度=O(n2) 2.4 顺序表算法设计思想 (1)双指针a) 元素之间的距离,或利用该距离找元素b) 元素值之间的比较c) 删除某一个或某一范围的值 (
7、2)置换a) 顺序表中部分元素之间的位置互换b) 改变部分元素次序c) 移动部分元素次序 (3)折半a) (对有序表)所求元素或所涉及操作与中间元素有关b) 查找 2.5静态链表 静态链表是借助来描述线性表的链式存储结构,静态链表表明使用数组实现线性表的操作不一定要移动元素,也可以“修改指针”。 2.6栈(一) 顺序栈(1) 注意栈顶指针top的位置,一般初始S.top=-1;栈满S.top=MaxSize-1;栈长S.top+1(2) 进栈判满,出栈判空;进栈时指针先加1,数据再进栈;出栈时数据先出栈,指针再减1(二) 共享栈两个栈的判空:top0=-1;top1=MaxSize判满:top
8、1-top0=1最大优点:只有整个存储空间被占满时才上溢,对存储效率无影响(三) 链栈操作受限的链表(插入最前元素,删除最前元素)之前有贴总结过,自己找吧(四) 出栈的合法性(*):1) 2) 若进栈顺序为1,2,3,4,i,n,出栈时若i出栈,则满足下面两个条件的:1.在i之前进栈的元素;2.在i之后出栈。则一定以进栈的逆序排列在i之后(或紧凑或分散)3) 出栈元素“个数”限制,若i出栈,i之前元素在i之后出栈,则i之后的元素个数一定大于等于i-1(五) 应用1) 括号匹配最基本的应用了栈的特点2) 表达式求值重点在中缀表达式转化为后缀表达式仔细看看P85 11题操作符#(*/+-)isp0
9、1536icp064213) 递归要明白高级语言中函数的调用就是通过栈实现的递归的利用使程序的效率变低2.7队列(一) 顺序队列(1) 队首指针和队尾指针规定指在什么位置,根据题或要求看仔细了(2) 判空和判满(依赖于第一条)(3) 进队和出队操作(依赖于第一条),王道单科书P72中的操作都是1.判满或判空2.操作数据3.修改指针,但这不是默认的,你看P76第8题,就是2011真题,它是先修改指针,再操作数据的(二) 循环队列(1) 逻辑顺时针的环(2) 实现除法取余运算(3) 基本操作a) Q.front=Q.rear=0b) Q.front=(Q.front+1)%MaxSizec) Q.
10、rear=(Q.rear+1)%MaxSized) 队列长度=(Q.rear-Q.front+MaxSize)%MaxSizee) 判空:Q.front=Q.rearf) 判满:牺牲一个单位:Q.front=(Q.rear+1)%MaxSize添加标志位(Q.size或tag,其实原理一样)(三) 链式队列(1) 操作受限的链表删除最前元素,插入最后元素(不同链表的时间复杂度看前面的贴,题中问哪种链表适合做队列或栈的其实就是问复杂度)(2) 操作时指针的修改原则,做队列的题时,要掌握几种队列的模型,能随手画出来,还有最重要的:题中要求队首指针和队尾指针指在哪(是指向元素还是元素上一个位置或者元
11、素下一个位置)(四) 双端队列(1) 不受限制的双端队列n个元素进队,出队序列的方式共n!种,即n个数全排列(2) 输入受限的双端队列a) 增加的出队方式为的子集b) *若末尾元素(这里指进队序列的最后一个元素)最先出队-进队序列固定-在出队序列中an(即末尾元素)的下一个元素只能是边缘元素,不可能是中间元素(注意这里的边缘和中间是相对而言的)。(3) 输出受限的双端队列a) 增加的出队方式为的子集b) *若末尾元素(这里指进队序列的最后一个元素)最先出队-全部元素进队后再出队-入队时最前面的两个元素在出队时一定相邻如果上面的你明白了,那么再看单科书P74-75 就简单了书中以4个元素为例,输
12、入受限的队列为什么得不到4 2 3 1 和 4 2 1 3 ,因为若4最先出队,2为中间元素不可能在4的后面;输出受限的队列为什么得不到4 2 3 1和 4 1 3 2 呢,因为若4最先出队,1和2 必相邻。再看P77 17题,元素依次入队后在出队,则a和b一定在出队序列中相邻,你就会快速准确的选出C,因为a和b不相邻,而且一定正确,比你一个一个试快得多。第三章 树和二叉树 3.1二叉树的存储(一) 顺序存储 完全二叉树 二叉树重要性质:1) 数组下标从1开始2) i1时,i/2是双亲3) 2i=N,i的左孩子为2i,否则无左孩子4) 2i+1结点的辈分关系b)若要NLR=LNR (即先序遍历
13、和中序遍历相同)则L为空,LRN=LNR(后序遍历和中序遍历相同)则R为空,若NLR=LRN则LR都为空,即只有根。3.4线索二叉树(一) 线索二叉树查找线性关系前驱或后继结点查找前驱结点查找后序结点先序线索二叉树(N L R)无左孩子:直接查找有左孩子:需要通过双亲结点无右孩子:直接查找有右孩子:有左孩子:左孩子结点 无左孩子:右孩子结点中序线索二叉树(L N R)无左孩子:直接查找有左孩子:左子树的最右下结点无右孩子:直接查找有右孩子:右子树的最左下的结点后序线索二叉树(L R N)无左孩子:直接查找有左孩子 有右孩子:右孩子结点 无右孩子:左孩子结点无右孩子:直接查找又右孩子:需要通过双
14、亲结点说明:1) 需要通过双亲结点,是指仅通过二叉链表是无法完成查找的,需借助栈或三叉链表来完成查找2) 先序线索二叉树查找先序后继结点时,左孩子优先右孩子;后序线索二叉树查找后序前驱结点时,右孩子优先左孩子(二) 树和二叉树的转换树对应二叉树叶结点无左孩子的结点非叶结点+根(N总-N叶+1或N非终端结点+1)无右孩子的结点无右兄弟的叶子结点度为0的结点(叶)(=无左孩子+无右孩子)有孩子,无右兄弟无孩子,有右兄弟度为1的结点既有孩子,又有右兄弟度为2的结点说明:1) 在树中,每一个非叶子结点,既度=1的结点都有一个无右兄弟的孩子结点,该结点转化为二叉树中的无右子树结点2) 二叉树中的叶子结点
15、一定来自树中的叶子结点3) 孩子兄弟表示法和二叉链表法,同一种存储方式的不同解释将一棵树转换为二叉树(三) 树,森林,二叉树树森林二叉树先根遍历先序遍历先序遍历后根遍历中序遍历中序遍历如果给出树的先根遍历与后根遍历可以唯一的构造出树所对应的二叉树,进而为一确定树。3.5平衡二叉树(AVL)(一) 二叉树的操作 插入:1) 二叉排序树是一种动态集合,该树是在查找过程中生成的2) 插入的结点一定是叶结点 删除:删除后重新链接确保二叉树性质不会丢失1) 若是叶结点,直接删除2) 结点只有一棵左或右子树,替代3) 结点有左右子树,有两种方式a) 孩子替代法(孩子的整棵树替代):左孩子替代,被删结点的右
16、子树连接到被删结点左子树的最右边;右孩子替代法,被删结点的左子树连接到被删结点右子树的最左边;b) 线性关系替代(转化为删除叶结点或只有一棵子树的结点):左子树的最右结点(叶结点或无右子树结点);右子树的最左结点(叶结点或无左子树结点)(二) 相关计算深度为h的平衡二叉树最少结点数描述:所有非叶子结点平衡因子均为1或-1n0=0,n1=1,n2=2nh=nh-2 + nh-1 + 1最多结点数描述:所有结点平衡因子均为02h-13.6排序二叉树判断二叉排序树查找路径是否合法(1) 按照给定的路径画出二叉排序树,若该树无分支则路径正确,否则错误(2) 快速判断:任意元素后面相邻的两个元素都大于或
17、都小于该元素(3) 快速构造二叉排序树,在给定插入元素序列中,一个结点的左孩子是其后第一个小于该结点值的结点,一个结点的右孩子是其后第一个大于该结点值的结点例:查询序列为:45 55 60 70 45后55 60都大于45,55后60 70 都大于55,所以该路径合法单科书156页第6题:A:95 22 91 24 94 7191后24小于91,94大于91,该序列不合法,其他的都合法3.7哈夫曼编码树(1) 带权路径长度最小的二叉树称为哈夫曼树,最优二叉树(2) N个结点构造的最优二叉树,共有2N-1个结点,无度为1的结点(3) 如果没有一个编码是另一个编码的前缀,则称这样的编码为前缀编码(
18、4) 0和1表示左子树和右子树不是确定的所以哈夫曼树不唯一第四章 查找(一) 查找的ASL查找类型存储结构表是否有序ASL顺序查找顺序存储链式存储有序表无序表无序表有序表折半查找顺序存储有序表分块查找顺序存储链式存储索引表有序查找表有序无序都采用顺序查找:索引表采用折半查找:若查找表有序,且采用折半查找: 注意:(1) 折半查找计算ASL时要画出判定树,而且要画出失败结点,这样通过判定树就可以计算ASL了(2) 分块查找有两个最优问题:1.s=根号n 时平均查找长度达到最小值;2.查找表有序时,索引表和查找表均采用折半查找,实现查找最优(二)B树B树一共要解决三个问题:1:定义问题 2:操作问
19、题 3:计算问题一、 定义问题关于B树的定义一共是5条,你可以直接记住,也不是很难理解,但我是这样记的:按照结点根结点(若不是终端结点)至少2棵子树,最多m棵子树每一结点内:1. 关键字升序排列2. 子树数=关键字数+1总体:叶结点数=关键字总数+1非根非叶结点至少棵,至多m棵叶结点出现在同一层的虚拟结点二、 操作问题(一)插入操作定义:关键字数=m-1为临界状态关键字数DFS和BFS唯一图的邻接表不唯一DFS和BFS不唯一2) 图的遍历和图的连通性无向图若连通:一次遍历就能访问图中所有顶点非连通:一次遍历仅能访问该结点所在连通分量的所有顶点有向图强连通(或初始结点到其它结点有路径):一次遍历即能访问所有结点非强连通:一次遍历无法完成所有结点的访问3) 对于无向图,BFS生成树,起点到其它顶点的路径是图中对应的最短路径也即是所有生成树中树高最小的4) 判断无向图G是一棵树的条件a) 无回路连通图b) 有n-1条边的连通图 (七) 图的应用一、 MST1. 存在相等权值的边MST树形可能不唯一各边权值各不相等MST树形唯一说明:所有权值均不相等,或者有相等的边,但是在构造最小生成树的过程中权值相等的边都被并入生成树的图,其最小生成树唯一2. MST性质:必存在一棵包含最小两栖边的最小生成树(1) Prim算法(通过点集判定边)选择与当前点集权
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1