堆中i结点的子树大小至多为2n/3的证明

本文通过数学归纳法证明了在任一含n个元素的堆中,至多有ceiling(n/(2^(h+1)))个高度为h的节点,并且证明了二叉堆中以节点i为根的、大小为n的子树上,i节点的子树大小至多为2n/3。

本人做特殊整理。

算法导论:6.2 保持堆的性质

 问题:在任一含n个元素的堆中,至多有ceiling(n/(2^(h+1)))个(即\left \lceil \frac{n}{2^{h+1}} \right \rceil)高度为h的节点。

分析

注意“高度为h的节点”的概念,是按照当前结点的子树决定的,而不是由整棵树决定,也就是所有的叶子结点的高度全部为0。

,如图所示,高度为1的节点有3个,分别为③,④,⑤。

数学归纳法证明:

(1)对于h=0, 即叶子结点的个数,由6.1-7习题可知,叶子结点的个数最多为\left \lceil \frac{n}{2} \right \rceil = \left \lceil \frac{n}{2^{h+1}} \right \rceil,即初始化成立。
(2)假设h=x成立,即高度为x的结点最多有\left \lceil \frac{n}{2^{x+1}} \right \rceil,
那么对于高度为h=x+1的结点应该为高度为x的父结点,所以高度为x+1的结点个数最多为\left \lceil \frac{n}{2^{x+1}} \right \rceil = \left \lceil \frac{n}{2^{(x+1) + 1}} \right \rceil = \left \lceil \frac{n}{2^{h+1}} \right \rceil.
命题得证。

问题:二叉堆中以节点i为根的、大小为n的子树上,i节点的子树大小至多为2n/3(最坏情况:底层恰好半满的时候),怎么证明?

证明:

二叉堆为完全二叉树,规定总size为n,要求根的左子树的最大size。(由于右子树size总是<=左子树size)。

那么显然,观察最底层节点数目为0, 1, 2...的情况,显然半满的时候左子树达到了最大。以下求此时左子树的大小:

设底层半满时节点数为x,则再加x个节点就是满树。

满树size=n + x = 2x * 2 - 1=4x-1 ①

可得n = 3x - 1,进而

x =(n+1)/3  ②。
满树时,左子树节点数 = (满树size - 1) / 2 ,代入① ②式,得到

 2x -1 = 2n/3 - 1/3 < 2n / 3。得证。

二叉树的形态 由 3结点可以构造出 ▁▁▁▁▁ 种不同形态的二叉树。 A. 2 B. 3 C. 4 D. 5 分数 1 作者 严蔚敏 单位 清华大学 若一棵非空二叉树先序遍历与后序遍历的序列正好相反,则该二叉树 ▁▁▁▁▁ 。 A. 所有结点均无左孩子 B. 所有结点均无右孩子 C. 只有一个叶子结点 D. 为任意二叉树 分数 1 作者 严蔚敏 单位 清华大学 二叉树的高度 若根节点为高度1,一棵具有 1025 个结点的二叉树的高度为 ▁▁▁▁▁ 。 A. 10 B. 11 C. 11~1025 之间 D. 10~1024 之间 分数 3 作者 考研真题 单位 浙江大学 对 n 个互不相同的符号进行哈夫曼编码。若生成的哈夫曼树共有 115 个结点,则 n 的值是: A. 56 B. 57 C. 58 D. 60 分数 2 作者 王俊玲 单位 集美大学 度为3的树中第4层上至多有( )个结点。 A. 12 B. 81 C. 27 D. 8 分数 2 作者 王俊玲 单位 集美大学 如果一个完全二叉树最底下一层为第六层(根为第一层)且该层共有8个叶结点,那么该完全二叉树共有多少个结点? A. 31 B. 39 C. 63 D. 71 分数 2 作者 王俊玲 单位 集美大学 若有一二叉树的总结点数为98,只有一个儿子的结点数为48,则该树的叶结点数是多少? A. 25 B. 50 C. 不确定 D. 这样的树不存在 分数 2 作者 王俊玲 单位 集美大学 对于二叉树,如果其中序遍历结果与前序遍历结果一样,那么可以断定该二叉树: A. 是完全二叉树 B. 所有结点都没有左儿子 C. 所有结点都没有右儿子 D. 这样的树不存在 分数 2 作者 王俊玲 单位 集美大学 已知一二叉树的后序和中序遍历的结果分别是FDEBGCA 和FDBEACG,那么该二叉树的前序遍历结果是什么? A. ABDFECG B. ABDEFCG C. ABDFEGC D. ABCDEFG 分数 2 作者 王俊玲 单位 集美大学 在上题的搜索树中删除结点1,那么删除后该搜索树的后序遍历结果是: A. 243765 B. 432765 C. 234567 D. 765432 分数 2 作者 王俊玲 单位 集美大学 若一AVL树的结点数是21,则该树的高度至多是多少?注:只有一个根节点的树高度为0 A. 4 B. 5 C. 6 D. 7 分数 2 作者 王俊玲 单位 集美大学 下列序列中哪个是最小? A. 2, 55, 52, 72, 28, 98, 71 B. 2, 28, 71, 72, 55, 98, 52 C. 2, 28, 52, 72, 55, 98, 71 D. 28, 2, 71, 72, 55, 98, 52 分数 2 作者 王俊玲 单位 集美大学 在最大 {97,76,65,50,49,13,27}中插入83后,该最大为: A. {97,76,65,83,49,13,27,50} B. {97,83,65,76,49,13,27,50} C. {97,83,65,76,50,13,27,49} D. {97,83,65,76,49,50,13,27} 分数 2 作者 王俊玲 单位 集美大学 对由同样的n个整数构成的二叉搜索树(查找树)和最小,下面哪个说法是不正确的: A. 二叉搜索树(查找树)高度大于等于最小高度 B. 对该二叉搜索树(查找树)进行中序遍历可得到从小到大的序列 C. 从最小根节点到其任何叶结点的路径上的结点值构成从小到大的序列 D. 对该最小进行按层序(level order)遍历可得到从小到大的序列 分数 2 作者 王俊玲 单位 集美大学 为五个使用频率不同的字符设计哈夫曼编码,下列方案中哪个不可能是哈夫曼编码? A. 00,100,101,110,111 B. 000,001,01,10,11 C. 0000,0001,001,01,1 D. 000,001,010,011,1 分数 2 作者 王俊玲 单位 集美大学 已知a、b两个元素均是所在集合的根结点,且分别位于数组分量32位置上,其parent值分别为-3,-2。问:将这两个集合按集合大小合并后,a和b的parent值分别是多少? A. -5,2 B. -5,3 C. -33 D. 2,-2 分数 2 作者 王东 单位 贵州师范学院 在下列存储形式中,( )不是树的存储形式。 A. 双亲表示法 B. 孩子链表表示法 C. 孩子兄弟表示法 D. 顺序存储表示法 分数 2 作者 王东 单位 贵州师范学院 引入二叉线索树的目的是( )。 A. 加快查找结点的前驱或后继的速度 B. 为了能在二叉树中方便的进行插入与删除 C. 为了能方便的找到双亲 D. 使二叉树的遍历结果唯一 分数 2 作者 王东 单位 贵州师范学院 以下说法中,正确的是( )。 A. 在完全二叉树中,叶子结点的双亲的左兄弟(若存在)一定不是叶子结点 B. 任何一棵二叉树,叶子结点个数为度为2结点数减1,即n0=n2-1 C. 完全二叉树不适合顺序存储结构,只有满二叉树适合顺序存储结构 D. 结点按完全二叉树层序编号的二叉树中,第i个结点的左孩子的编号为2i 分数 2 作者 王东 单位 贵州师范学院 若一棵深度为6的完全二叉树的第6层有3个叶子结点,则该二叉树共有( )个叶子结点。 A. 17 B. 18 C. 19 D. 20 分数 2 作者 王东 单位 贵州师范学院 若一棵二叉树有126个结点,在第7层(根结点在第1层)至多有( )个结点。 A. 32 B. 64 C. 63 D. 不存在第7层 分数 2 作者 王东 单位 贵州师范学院 在一棵完全二叉树中,其根的序号为1,(  )可判定序号为 p和q 的两个结点是否在同一层。 A. ⌊log 2 ​ p⌋=⌊log 2 ​ q⌋ B. log 2 ​ p=log 2 ​ q C. ⌊log 2 ​ p⌋+1=⌊log 2 ​ q⌋ D. ⌊log 2 ​ p⌋=⌊log 2 ​ q⌋+1 分数 2 作者 王东 单位 贵州师范学院 在任何一棵二叉树中,若结点a有左孩子b、右孩子c,则在结点的先序序列、中序序列、后序序列中,( )。 A. 结点b一定在结点a的前面 B. 结点a一定在结点c的前面 C. 结点b一定在结点c的前面 D. 结点a一定在结点b的前面 分数 2 作者 YJ 单位 西南石油大学 在完全二叉树中,若一个结点是叶结点,则它没( )。 A. 左子结点 B. 右子结点 C. 左子结点和右子结点 D. 左子结点,右子结点和兄弟结点 分数 2 作者 YJ 单位 西南石油大学 由3结点可以构造出多少种不同的二叉树( ) A. 2 B. 3 C. 4 D. 5 分数 2 作者 YJ 单位 西南石油大学 下面几个符号串编码集合中,不是前缀编码的是( )。 A. {0,10,110,1111} B. {11,10,001,101,0001} C. {00,010,0110,1000} D. {b,c,aa,ac,aba,abb,abc} 分数 2 作者 YJ 单位 西南石油大学 一棵有n个结点的二叉树,按层次从上到下,同一层从左到右顺序存储在一维数组A[1..n]中,则二叉树中第i个结点(i从1开始用上述方法编号)的右孩子在数组A中的位置是( )。 A. A[2i](2i<=n) B. A[2i+1](2i+1<=n) C. A[i-2] D. 条件不充分,无法确定 分数 2 作者 YJ 单位 西南石油大学 在二叉树的二叉链表结构中,指针p所指结点为叶子结点的条件是( )。 A. p=NULL B. p->lchild==NULL && p->rchlid==NULL C. p->lchild==NULL D. p->rchlid==NULL 分数 2 作者 YJ 单位 西南石油大学 深度为k的完全二叉树至少有(1)个结点至多有(2)个结点。 A. (1)2k-1 (2)2k-1 B. (1)2k (2)2 k -1 C. (1)2 k (2)2 k +1 D. (1)2 k−1 (2)2 k -1 分数 2 作者 YJ 单位 西南石油大学 高度为8的完全二叉树至少有( )个叶子结点。 A. 128 B. 63 C. 64 D. 32 分数 2 作者 YJ 单位 西南石油大学 一个深度为k的,具有最少结点数的完全二叉树按层次,(同层次从左到右)用自然数依此对结点编号,则编号最小的叶子的序号是( )。 A. 2 k−2 B. 2 k−2 +1 C. 2 k−1 +1 D. 2 k−1 分数 2 作者 YJ 单位 西南石油大学 二叉树的先序序列和中序序列相同的条件是( )。 A. 任何结点至多只有左子女的二叉树 B. 任何结点至多只有右子女的二叉树 C. 右子树为空 D. 左子树为空 分数 2 作者 考研真题 单位 浙江大学 给定平衡二叉树如下图所示,插入关键字 23 后,根中的关键字是: t1.png A. 16 B. 20 C. 23 D. 25 分数 2 作者 考研真题 单位 浙江大学 将关键字 6、9、1、5、8、4、7 依次插入到初始为空的大根 H 中,得到的 H 是: A. 9、8、7、6、5、4、1 B. 9、8、7、5、6、1、4 C. 9、8、7、5、6、4、1 D. 9、6、7、5、8、4、1 分数 1 作者 张泳 单位 浙大城市学院 若一棵3次树中有2个度为3的节点,1个度为2的节点,2个度为1的节点,该树一共有 ( ) 个节点 A. 5 B. 8 C. 10 D. 11 分数 1 作者 张泳 单位 浙大城市学院 以下关于二叉树的说法中正确的是( ) A. 二叉树中每个节点的度均为2 B. 二叉树中至少有一个节点的度为2 C. 二叉树中每个节点的度可以小于2 D. 二叉树中至少有一个节点 分数 1 作者 张泳 单位 浙大城市学院 一棵二叉树中有7个叶子节点和5个单分支节点,其总共有( )个节点 A. 16 B. 18 C. 12 D. 31 分数 1 作者 张泳 单位 浙大城市学院 深度为5的二叉树至多有 ( )个节点 A. 16 B. 32 C. 31 D. 10 分数 1 作者 张泳 单位 浙大城市学院 一个具有1025个节点的二叉树的高h为( ) A. 11 B. 10 C. 11~1025 D. 12~1024 分数 1 作者 张泳 单位 浙大城市学院 一棵完全二叉树中有501个叶子节点,则至少有 ( ) 个节点 A. 501 B. 502 C. 1001 D. 1002 分数 1 作者 张泳 单位 浙大城市学院 一棵高度为8的完全二叉树至少有( )叶子节点 A. 63 B. 64 C. 127 D. 128 分数 1 作者 张泳 单位 浙大城市学院 一棵满二叉树中127个节点,其中叶子节点的个数是( ) A. 63 B. 64 C. 65 D. 不确定 分数 1 作者 张泳 单位 浙大城市学院 某二叉树的先序遍历序列和后序遍历序列正好相反,则该二叉树一定是( ) A. 空或只有一个节点 B. 完全二叉树 C. 二叉排序树 D. 高度等于其节点数 分数 1 作者 张泳 单位 浙大城市学院 一棵二叉树的先序遍历序列为ABCDEF,中序遍历序列为CBAEDF,则后序遍历序列为( ) A. CBEFDA B. FEDCBA C. CBEDFA D. 不确定 分数 1 作者 严蔚敏 单位 清华大学 若一棵非空二叉树 ▁▁▁▁▁,则中序遍历与层次遍历的序列完全相同。 A. 所有结点均无左孩子 B. 所有结点均无右孩子 C. 只有一个叶子结点 D. 为任意二叉树 分数 1 作者 李祥 单位 湖北经济学院 若一棵非空二叉树 ▁▁▁▁▁,则中序遍历与层次遍历的序列正好相反。 A. 所有结点均无左孩子 B. 所有结点均无右孩子 C. 只有一个叶子结点 D. 为任意二叉树 分数 1 作者 李祥 单位 湖北经济学院 对一棵二叉树的结点从 1 开始顺序编号。要求每个结点的编号都小于其子树所有结点的编号,且左子树所有结点的编号都小于右子树所有结点的编号。可采用 ▁▁▁▁▁ 实现编号。 A. 先序遍历 B. 后序遍历 C. 中序遍历 D. 层次遍历 分数 1 作者 严蔚敏 单位 清华大学 分别按以下顺序插入结点到空二叉排序树中,▁▁▁▁▁ 与其它三个序列所得到的结果不同。 A. 10, 8, 9, 6, 12, 11, 13 B. 10, 12, 11, 13, 8, 6, 9 C. 10, 6, 8, 9, 12, 11, 13 D.
最新发布
10-24
静态链表示意图:2.2 顺序表与链表的比较存储密度比较:顺序表:只存储数据元素、预分配存储空间链表:指针的结构性开销、链表中的元素个数没有限制按位查找:顺序表:O(1),随机存取链表:O(n),顺序存取插入和删除:顺序表:O(n),平均移动表长一半的元素链表:不用移动元素,合适位置的指针——O(1)时间复杂度:顺序表:若线性表频繁查找却很少进行插入和删除操作链表:若线性表需频繁插入和删除时空间复杂度:顺序表:知道线性表的大致长度,空间效率会更高链表:若线性表中元素个数变化较大或者未知2.3 栈        定义:限定仅在一端(栈顶)进行插入和删除操作的线性表,后进先出。栈示意图:        时间复杂度(插入与删除):顺序栈与链栈均为O(1)        空间复杂度:链栈多一个指针域,结构性开销较大,使用过程中元素个数变化较大时,用链栈;反之顺序栈。        出栈元素不同排列的个数:   (卡特兰数)        共享栈: 两个栈共享一片内存空间, 两个栈从两边往中间增长。卡特兰数的应用:存储结构:顺序栈初始化:top=-1链栈初始化:top=NULL栈的应用:        1) 括号匹配        2) 递归        3) 中缀表达式 转 后缀表达式        4) 中缀表达式:设两个栈(数据栈和运算符栈),根据运算符栈的优先级进行运算。2.4 队列        定义: 只允许在一端插入, 在另一端删除。具有先进先出的特点。队列示意图:        时间复杂度:均为O(1)        空间复杂度:链队列多一个指针域,结构性开销较大;循环队列存在浪费空间和溢出问题。使用过程中元素个数变化较大时,用链队列;反之循环队列。        双端队列: 只允许从两端插入、两端删除的线性表。双端队列示意图: 存储结构:        链队列:队头指针指向队头元素的前一个位置,队尾指针指向队尾元素,先进先出。        循环队列:                1)队空:front=rear                2)队满:(rear+1)%QueueSize=front                3)队列元素个数:(队尾-队头+队长)%队长==(rear-front+QueueSize)%QueueSize队列的应用:        1) 树的层次遍历        2) 图的广度优先遍历2.4 数组与特殊矩阵一维数组的存储结构:二维数组的存储结构: 对称矩阵的压缩(行优先):下三角矩阵的压缩(行优先):  上三角(行优先):三对角矩阵的压缩(行优先):稀疏矩阵压缩:十字链表法压缩稀疏矩阵:2.5 串        串,即字符串(String)是由零个或多个字符组成的有限序列。串是一种特殊的线性表,数据元素之间呈线性关系。字符串模式匹配:        1)朴素模式匹配算法        2)KMP算法手算KMP的next数组示意图:求next[2] :求next[3]: 求next[4]: 求next[5]: C语言求KMP的next数组代码示例:void Createnext(char *sub, int *next){ assert(sub != NULL && next != NULL); int j = 2; //模式串的next指针 int k = 0; //next数组的回溯值,初始化为next[1]=0 int lenSub = strlen(sub); assert(lenSub != 0); next[0] = -1; next[1] = 0; while (j < lenSub){ if (sub[j-1] == sub[k]){ next[j] = ++k; j++; } else{ k = next[k]; if (k == -1){ k = 0; next[j] = k; j++; } } }}求nextValue:void nextValue(char *sub, int *next) { int lenSub = strlen(sub); for(int j=2;j<lensub; j++){ if(sub[j]==sub[next[j]]) next[j]=next[next[j]] }}备注:         1) 实现next有多种不同方式, 对应不同的next数组使用        2) 根据实现方式不同, next数组整体+1不影响KMP算法。第三章 树和二叉树3.1 树和森林        定义(树):n(n≥0)个结点(数据元素)的有限集合,当 n=0 时,称为空树。3.1.1 树的基本术语        结点的度:结点所拥有的子树的个数。        叶子结点:度为 0 的结点,也称为终端结点。        分支结点:度不为 0 的结点,也称为非终端结点。        孩子:树中某结点子树的根结点称为这个结点的孩子结点。        双亲:这个结点称为它孩子结点的双亲结点。        兄弟:具有同一个双亲的孩子结点互称为兄弟。        路径:结点序列 n1, n2, …, nk 称为一条由 n1 至 nk 的路径,当且仅当满足结点 ni 是 ni+1 的双亲(1<=i<k)的关系。        路径长度:路径上经过的边的个数。        祖先、子孙:如果有一条路径从结点 x 到结点 y,则 x 称为 y 的祖先,而 y 称为 x 的子孙。        结点所在层数:根结点的层数为 1;对其余结点,若某结点在第 k 层,则其孩子结点在第 k+1 层。        树的深度(高度):树中所有结点的最大层数。        树的宽度:树中每一层结点个数的最大值。        树的度:树中各结点度的最大值。        树的路径长度:  从根到每个结点的路径长度总和        备注: 在线性结构中,逻辑关系表现为前驱——后继,一对一; 在树结构中,逻辑关系表现为双亲——孩子,一对多。        森林: 森林是m(m≥0)棵互不相交的树的集合, m可为0, 即空森林。3.1.2 树的性质        结点数=总度数+1        度为m的树第 i 层至多有 个结点(i≥1)        高度为h的m叉树至多有 个结点        具有n个结点的m叉树的最小高度为 最小高度推理过程图:3.1.3 树与森林的遍历树的遍历:先根遍历(先根后子树)后根遍历(先子树后根)层序遍历森林的遍历:前序遍历(先根, 后子树)中序遍历(先子树后根, 其实就是后序遍历树)区别与联系:         1) 树的前序遍历等价于其树转化二叉树的前序遍历!        2) 树的后序遍历等价于其树转化二叉树的中序遍历!3.1.4 树的存储结构双亲表示法图:孩子表示法图:孩子兄弟表示法图(树/森林转化为二叉树):3.1.5 树转二叉树在树转为二叉树后, 有以下结论:        1) 树的叶子结点数量 = 二叉树左空指针数量(形象理解为树越宽, 兄弟越多, 越是向右长)        2) 树的非叶子结点数量 = 二叉树右空指针-1(非叶子必有儿子, 右指针由儿子提供, -1是根节点多了一个右空指针)3.2 二叉树3.2.1 二叉树的性质斜树:左斜树:所有结点都只有左子树的二叉树右斜树:所有结点都只有右子树的二叉树        满二叉树:所有分支结点都存在左子树和右子树,且所有叶子都在同一层上的二叉树        完全二叉树:在满二叉树中,从最后一个结点开始,连续去掉任意个结点得到的二叉树完全二叉树特点:叶子结点只能出现在最下两层且最下层的叶子结点都集中在二叉树的左面完全二叉树中如果有度为 1 的结点,只可能有一个,且该结点只有左孩子深度为 k 的完全二叉树在 k-1 层上一定是满二叉树在同样结点个数的二叉树中,完全二叉树的深度最小        性质:在二叉树中,如果叶子结点数为 n0,度为 2结点数为 n2,则有: n0=n2+1证明: 设 n 为二叉树的结点总数,n1 为二叉树中度为 1 的结点数,则有: n=n0+n1+n2        在二叉树中,除了根结点外,其余结点都有唯一的一个分枝进入,一个度为 1 的结点射出一个分枝,一个度为 2结点射出两个分枝,所以有:n=n1+2n2+1        性质:二叉树的第 i 层上最多有个结点(i≥1)        性质:一棵深度为 k 的二叉树中,最多有 个结点        性质:具有 n 个结点的完全二叉树的深度为 向下取整+1 (或向上取整)证明:设具有 n 个结点的完全二叉树的深度为 k,则:≤n  <对不等式取对数,有:k-1 ≤ <k即:<k ≤ +1由于 k 是整数,故必有k= +1         性质:对一棵具有 n 个结点的完全二叉树中从 1 开始按层序编号,对于任意的序号为 i(1≤i≤n)的结点(简称结点 i),有:如果 i>1,则结点 i 的双亲结点的序号为 i/2,否则结点 i 无双亲结点如果 2i≤n,则结点 i 的左孩子的序号为 2i,否则结点 i 无左孩子如果 2i+1≤n,则结点 i 的右孩子的序号为2i+1,否则结点 i 无右孩子        性质:若已知一棵二叉树的前序序列和中序序列,或者中序序列和后序序列,能唯一确定一颗二叉树。 3.2.2 二叉树的遍历        从根结点出发,按照某种次序访问树中所有结点,并且每个结点仅被访问一次。前序遍历(深度优先遍历)中序遍历后序遍历层序遍历(广度优先遍历)3.2.3 二叉树的存储链式存储图:顺序存储图:3.2.4 线索二叉树        利用二叉树中n+1个空指针, 将指针指向结点的前驱和后继。线索二叉树是加上线索的链表结构,  是一种物理结构存储结构:示例图:三种线索化的对比图: 各自特点:3.3 哈夫曼树和哈夫曼编码        带权路径长度(WPL):从根结点到各个叶子结点的路径长度与相应叶子结点权值的乘积之和        最优二叉树(哈夫曼树):给定一组具有确定权值的叶子结点,带权路径长度最小的二叉树特点:权值越大的叶子结点越靠近根结点只有度为 0 和度为 2结点,不存在度为 1 的结点构造过程中共新建了n-1个结点, 因此总结点数为2n-1        前缀编码:在一组编码中,任一编码都不是其它任何编码的前缀, 前缀编码保证了在解码时不会有多种可能。         度为m的哈夫曼树: 通过只有度为m和度为0求解非叶子结点 3.4 并查集        存储结构: 双亲表示法        实现功能: 并查(并两个集合, 查根结点)        优化: 小树并到大树, "高树变矮树"(压缩路径)第四章 图        定义:顶点集V和边集E组成,记为G = (V, E)        注意:线性表可以是空表,树可以是空树,但图不可以是空,即V一定是非空集, 边集E可以为空        子图:若图G=(V, E),G&#39;=(V&#39;, E&#39;),如果V&#39; 属于 V 且E&#39; 属于E,则称图G&#39;是G的子图4.1 图的基本概念图的分类:        无向边:表示为(vi,vj),顶点vi和vj之间的边没有方向        有向边(弧):表示为<vi,vj>,从vi 到vj 的边有方向, vi为弧尾, vj为弧头        稠密图:边数很多的图        稀疏图:边数很少的图        无向完全图:无向图中,任意两个顶点之间都存在边        有向完全图:有向图中,任意两个顶点之间都存在方向相反的两条弧度、入度和出度:        顶点的度:在无向图中,顶点 v 的度是指依附于该顶点的边数,通常记为TD (v)        顶点的入度:在有向图中,顶点 v 的入度是指以该顶点为弧头的弧的数目,记为ID (v);        顶点的出度:在有向图中,顶点 v 的出度是指以该顶点为弧尾的弧的数目,记为OD (v);        握手定理: 路径:         回路(环):第一个顶点和最后一个顶点相同的路径        简单路径:序列中顶点不重复出现的路径        简单回路(简单环):除第一个和最后一个顶点外,其余顶点不重复出现的回路。        路径长度:非带权图——路径上边的个数        路径长度:带权图——路径上边的权值之和         极大连通子图: 连通的情况下, 包含尽可能多的边和顶点, 也称连通分量        极小连通子图: 删除该子图中任何一条b边, 子图不再连通, 如生成树无向连通图:        连通顶点:在无向图中,如果顶点vi和顶点vj(i≠j)之间有路径,则称顶点vi和vj是连通的        连通图:在无向图中,如果任意两个顶点都是连通的,则称该无向图是连通图        连通分量:非连通图的极大连通子图、连通分量是对无向图的一种划分连通分量示意图:有向强连通图、强连通分量:        强连通顶点:在有向图中,如果从顶点vi到顶点vj和从顶点vj到顶点vi均有路径,则称顶点vi和vj是强连通的        强连通图:在有向图中,如果任意两个顶点都是强连通的,则称该有向图是强连通图        强连通分量:非强连通图的极大连通子图强连通分量示意图: 子图与生成子图:常考点无向图:        所有顶点的度之和=2|E|        若G是连通图,则最少有 n-1 条边(树),若 |E|>n-1,则一定有回路        若G是非连通图,则最多可能有 条边 (n-1个完全图+1个孤点)        无向完全图共有条边有向图:        所有顶点的出度之和=入度之和=|E|        所有顶点的度之和=2|E|        若G是强连通图,则最少有 n 条边(形成回路)        有向完全图共有条边图的遍历:从图中某一顶点出发访问图中所有顶,并且每个结点仅被访问一次。深度优先遍历序列(dfs)广度优先遍历序列(bfs)    备注:  调⽤BFS/DFS函数的次数 = 连通分量数4.2 图的存储结构 邻接矩阵:一维数组:存储图中顶点的信息二维数组(邻接矩阵):存储图中各顶点之间的邻接关系特点:一个图能唯一确定一个邻接矩阵,存储稀疏图时,浪费空间。空间复杂度为: O()。示意图:性质 (行*列) :邻接表:顶点表:所有边表的头指针和存储顶点信息的一维数组边表(邻接表):顶点 v 的所有邻接点链成的单链表示意图:特点:空间复杂度为:O(n+e), 适合存储稀疏图。两者区别:十字链表法图:备注:         1) 十字链表只用于存储有向图        2) 顺着绿色线路找: 找到指定顶点的所有出边        3) 顺着橙色线路找: 找到指定顶点的所有入边        4) 空间复杂度:O(|V|+|E|)邻接多重表图:备注:        1) 邻接多重表只适用于存储无向图        2) 空间复杂度:O(|V|+|E|)四者区别: 4.3 最小生成树        生成树:连通图的生成树是包含全部顶点的一个极小连通子图, 可用DFS和BFS生成。        生成树的代价:在无向连通网中,生成树上各边的权值之和        最小生成树:在无向连通网中,代价最小的生成树        性质: 各边权值互不相等时, 最小生成树是唯一的。边数为顶点数-1生成森林示意图:4.3.1 Prim算法        从某⼀个顶点开始构建⽣成树;每次将代价最⼩的新顶点纳⼊⽣成树,直到所有顶点都纳⼊为⽌。基于贪心算法的策略。        时间复杂度:O(|V|2) 适合⽤于边稠密图。4.3.2 Kruskal 算法(克鲁斯卡尔)        每次选择⼀条权值最⼩的边,使这条边的两头连通(原本已经连通的就不选), 直到所有结点都连通。基于贪心算法的策略。        时间复杂度:O( |E|log2|E| ) 适合⽤于边稀疏图。4.4 最短路径        非带权图: 边数最少的路径(广度优先遍历)        带权图: 边上的权值之和最少的路径4.4.1 Dijkstra算法        时间复杂度:O(n2)        备注: Dijkstra 算法不适⽤于有负权值的带权图4.4.2 Floyd算法核心代码:        时间复杂度:O(n3)        备注: 可以⽤于负权值带权图, 不能解决带有“负权回路”的图三者区别:4.5 有向⽆环图(DAG)描述表达式 (简化前) :描述表达式 (简化后) :4.6 拓扑排序        AOV⽹(Activity On Vertex NetWork,⽤顶点表示活动的⽹): ⽤DAG图(有向⽆环图)表示⼀个⼯程。顶点表示活动,有向边表示活动Vi必须先于活动Vj进⾏如图:拓扑排序的实现:        ① 从AOV⽹中选择⼀个没有前驱(⼊度为0)的顶点并输出。        ② 从⽹中删除该顶点和所有以它为起点的有向边。        ③ 重复①和②直到当前的AOV⽹为空或当前⽹中不存在⽆前驱的顶点为⽌。逆拓扑排序(可用DFS算法实现):        ① 从AOV⽹中选择⼀个没有后继(出度为0)的顶点并输出。        ② 从⽹中删除该顶点和所有以它为终点的有向边。        ③ 重复①和②直到当前的AOV⽹为空备注: 上三角(对角线为0)矩阵, 必不存在环, 拓扑序列必存在, 但拓扑不唯一。(拓扑唯一, 图不唯一)4.7 关键路径        在带权有向图中,以顶点表示事件,以有向边表示活动,以边上的权值表示完成该活动的开销(如完成活动所需的时间),称之为⽤边表示活动的⽹络,简称AOE⽹示意图:        关键活动: 从源点到汇点的有向路径可能有多条,所有路径中,具有最⼤路径⻓度的路径称为 关键路径,⽽把关键路径上的活动称为关键活动。        事件vk的最早发⽣时间: 决定了所有从vk开始的活动能够开⼯的最早时间。        活动ai的最早开始时间: 指该活动弧的起点所表⽰的事件的最早发⽣时间。        事件vk的最迟发⽣时间: 它是指在不推迟整个⼯程完成的前提下,该事件最迟必须发⽣的时间。        活动ai的最迟开始时间: 它是指该活动弧的终点所表示事件的最迟发⽣时间与该活动所需时间之差。        活动ai的时间余量:表⽰在不增加完成整个⼯程所需总时间的情况下,活动ai可以拖延的时间。d(k)=0的活动就是关键活动, 由关键活动可得关键路径。示例图:第五章 查找        静态查找 :不涉及插入和删除操作的查找        动态查找 :涉及插入和删除操作的查找        查找⻓度: 在查找运算中,需要对⽐关键字的次数称为查找⻓度        平均查找长度:衡量查找算法的效率公式:5.1 顺序查找(线性查找):        顺序查找适合于存储结构为顺序存储或链接存储的线性表。  基本思想:从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。        时间复杂度: O(n)。有序顺序查找的ASL图:        无序查找失败时的平均查找长度:  n+1次 (带哨兵的情况)5. 2 折半查找:        元素必须是有序的,顺序存储结构。判定树是一颗平衡二叉树, 树高 (由n=-1得来)。        基本思想:用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表。        公式:mid=(low+high)/2, 即mid=low+1/2*(high-low);           1)相等,mid位置的元素即为所求           2)>,low=mid+1;                3)<,high=mid-1。        时间复杂度: 二叉判定树的构造:         备注:对于静态查找表,一次排序后不再变化,折半查找能得到不错的效率。但对于需要频繁执行插入或删除操作的数据集来说,不建议使用。失败结点的ASL不是方形结点, 而是其父节点。5.3 分块查找        分块查找,⼜称索引顺序查找。        基本思想:将查找表分为若干子块, 块内的元素可以无序, 块间的元素是有序的, 即前一个快的最大元素小于后一个块的最大元素。再建立索引表, 索引表中的每个元素含有各块的最大关键字和第一个元素的地址。索引表按关键字有序排列。示意图:备注:         1) 设索引查找和块内查找的平均查找⻓度分别为LI、LS,则分块查找的平均查找⻓度为ASL=LI + LS        2) 将长度为n的查找表均匀分为b块, 每块s个记录, 在等概率情况下, 若在块内和索引表中均采用顺序查找, 则平均查找长度为:5.4 二叉排序树        又称二叉查找树(BST,Binary Search Tree), 是具有如下性质的二叉树:左子树结点值 < 根结点值 < 右子树结点值        二叉排序树的插入:  新插入的结点 一定是叶子。二叉排序树的删除        1) 情况一, 删除叶结点, 直接删除        2) 情况二, 待删除结点只有一颗子树, 让子树代替待删除结点        3) 情况三, 待删除结点有左, 右子树, 则令待删除的直接前驱(或直接后继(中序遍历))代替待删除结点。示意图: (30为直接前驱, 60为直接后继)平均查找效率: 主要取决于树的高度。时间复杂度: 5.5 平衡二叉树        简称平衡树(AVL树), 树上任一结点的左子树和右子树的 高度之差不超过1。 结点的平衡因子=左子树高-右子树高。平衡二叉树的插: LL型:RR型:RL型:LR型:        平衡二叉树的删除: 同上考点:        假设以表示深度为h的平衡树中含有的最少结点数。 则有 = 0, = 1, = 2,并且有=  +          时间复杂度: 5.6 红黑树        与AVL树相比, 插入/删除 很多时候不会破坏“红黑”特性,无需频繁调整树的形态。因为AVL是高度差严格要求不超过1, 红黑树高度差不超过2倍, 较为宽泛。定义:        ①每个结点或是红色,或是黑色的        ②根节点是黑色的        ③叶结点(外部结点、NULL结点、失败结点)均是黑色的        ④不存在两个相邻的红结点(即红结点的父节点和孩子结点均是黑色)        ⑤对每个结点,从该节点到任一叶结点的简单路径上,所含黑结点的数目相同        口诀: 左根右,根叶黑 不红红,黑路同示例图:性质:        性质1:从根节点到叶结点的最长路径不大于最短路径的2倍 (红结点只能穿插 在各个黑结点中间)        性质2:有n个内部节点的红黑树高度          结论: 若根节点黑高为h,内部结点数(关键字)最多有 , 最少有示例图:红黑树的插入操作:红黑树的插入示例图:         红黑树的删除: 和“二叉排序树的删除”一样! 具体还是算了吧, 放过自己。。。        时间复杂度: 5.7 B树        B树,⼜称多路平衡查找树,B树中所被允许的孩⼦个数的最⼤值称为B树的阶,通常⽤m表示。 m阶B树的特性:        1)树中每个结点⾄多有m棵⼦树,即⾄多含有m-1个关键字。        2)若根结点不是终端结点,则⾄少有两棵⼦树。        3)除根结点外的所有⾮叶结点⾄少有 棵⼦树,即⾄少含有个关键字。         4) 所有的叶结点都出现在同⼀层次上,并且不带信息, ( 指向这些结点的指针为空 ) 。        5) 最小高度:    (n为关键字, 注意区分结点)        6) 最大高度:         7) 所有⼦树⾼度要相同        8) 叶结点对应查找失败的情况, 即n个关键字有n+1个叶子结点示例图: B树的插入(5阶为例):B树的删除:        1) 若被删除关键字在终端节点,则直接删除该关键字 (要注意节点关键字个数是否低于下限 ⌈m/2⌉ − 1)        2) 若被删除关键字在⾮终端节点,则⽤直接前驱或直接后继来替代被删除的关键字 删除77:删除38:删除90:        3) 若被删除关键字所在结点删除前的关键字个数低于下限,且此时与该结点相邻的左、右兄弟结 点的关键字个数均=⌈m/2⌉ − 1,则将关键字删除后与左(或右)兄弟结点及双亲结点中的关键字进⾏合并 删除49: 5.8 B+树⼀棵m阶的B+树需满⾜下列条件        1)每个分⽀结点最多有m棵⼦树(孩⼦结点)。        2)⾮叶根结点⾄少有两棵⼦树,其他每个分⽀结点⾄少有 ⌈m/2⌉ 棵⼦树。        3结点的⼦树个数与关键字个数相等。        4)所有叶结点包含全部关键字及指向相应记录的指针,叶结点中将关键字按⼤⼩顺序排列,并且相邻叶结点按⼤⼩顺序相互链接起来        5)所有分⽀结点中仅包含它的各个⼦结点中关键字的最⼤值及指向其⼦结点的指针。所有⾮叶结点仅起索引作⽤,        6) 所有⼦树⾼度要相同B+树示例图:B+树与B树的对比图:5.9 哈希表(Hash)        根据数据元素的关键字 计算出它在散列表中的存储地址。        哈希函数: 建⽴了“关键字”→“存储地址”的映射关系。        冲突(碰撞):在散列表中插⼊⼀个数据元素时,需要根据关键字的值确定其存储地址,若 该地址已经存储了其他元素,则称这种情况为“冲突(碰撞)”        同义词:若不同的关键字通过散列函数映射到同⼀个存储地址,则称它们为“同义词”        复杂度分析:对于无冲突的Hash表而言,查找复杂度为O(1) 5.9.1 构造哈希函数        1) 除留余数法 —— H(key) = key % p, 取⼀个不⼤于m但最接近或等于m的质数p        适⽤场景:较为通⽤,只要关键字是整数即可        2) 直接定址法 —— H(key) = key 或 H(key) = a*key + b        适⽤场景:关键字分布基本连续        3) 数字分析法 —— 选取数码分布较为均匀的若⼲位作为散列地        适⽤场景:关键字集合已知,且关键字的某⼏个数码位分布均匀        4) 平⽅取中法(二次探测法)——取关键字的平⽅值的中间⼏位作为散列地址        适⽤场景:关键字的每位取值都不够均匀。5.9.2 处理冲突拉链法示意图:开放定址法:        1) 线性探测法        2) 平⽅探测法        3) 双散列法        4) 伪随机序列法示意图:        删除操作: 采用开放定址法时, 只能逻辑删除。        装填因子: 表中记录数 / 散列表长度 。        备注: 平均查找长度的查找失败包含不放元素的情况。(特殊: 根据散列函数来算: 2010真题)        聚集: 处理冲突的方法选取不当,而导致不同关键字的元素对同一散列地址进行争夺的现象第六章 排序        稳定 :如果a原本在b前面,而a=b,排序之后a仍然在b的前面;        内排序 :所有排序操作都在内存中完成;        外排序 :由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行。参考博客:超详细十大经典排序算法总结(java代码)c或者cpp的也可以明白_Top_Spirit的博客-CSDN博客6.1 直接插入排序动图演示:         优化: 折半插入排序6.2 希尔排序        又称缩小增量排序, 先将待排序表分割成若⼲形如 L[i, i + d, i + 2d,…, i + kd] 的“特殊”⼦表,对各个⼦表分别进⾏直接插⼊排序。缩⼩增量d,重复上述过程,直到d=1为⽌。建议每次将增量缩⼩⼀半。示例图:6.3 冒泡排序动图演示:6.4 快速排序算法思想:        1) 在待排序表L[1…n]中任取⼀个元素pivot作为枢轴(或基准)        2) 通过⼀趟排序将待排序表划分为独⽴的两部分L[1…k-1]和L[k+1…n],使得L[1…k-1]中的所有元素⼩于pivot,L[k+1…n]中的所有元素⼤于等于 pivot,则pivot放在了其最终位置L(k)上,这个过程称为⼀次“划分”。        3) 然后分别递归地对两个⼦表重复上述过程,直每部分内只有⼀个元素或空为⽌,即所有元素放在了其最终位置上。示例图:  6.5 简单选择排序        算法思想: 每⼀趟在待排序元素中选取关键字最⼩的元素加⼊有序⼦序列。动画演示:6.6 排序        ⼤根: 若满⾜:L(i)≥L(2i)且L(i)≥L(2i+1) (1 ≤ i ≤n/2 )        ⼩根: 若满⾜:L(i)≤L(2i)且L(i)≤L(2i+1) (1 ≤ i ≤n/2 )大根示例图:6.6.1 建立大根        思路:从开始, 把所有⾮终端结点都检查⼀遍,是否满足大根的要求,如果不满⾜,则进⾏调整。若元素互换破坏了下⼀级的,则采⽤相同的方法继续往下调整(⼩元素不断“下坠”)小元素下坠示例图:          结论: 建的过程,关键字对⽐次数不超过4n,建时间复杂度=O(n)6.6.2 的插入与删除        插入: 将新增元素放到表尾, 而后根据大小进行上升调整。        删除: 被删除的元素⽤底元素替代,然后让该 元素不断“下坠”,直到⽆法下坠为⽌排序动图演示:6.7 归并排序        该算法是采用分治法, 把两个或多个已经有序的序列合并成⼀个。2路归并图:        结论:n个元素进⾏k路归并排序,归并趟数= 6.8 基数排序 (低位优先)        基数排序是非比较的排序算法,对每一位进行排序,从最低位开始排序,复杂度为O(kn),为数组长度,k为数组中的数的最大的位数;动图演示:         时间复杂度: ⼀趟分配O(n),⼀趟收集O(r),总共 d 趟分配、收集,总的时间复杂度=O(d(n+r)) , 其中把d为关键字拆 为d个部分, r为每个部分可能 取得 r 个值。基数排序适用场景:        ①数据元素的关键字可以⽅便地拆分为 d 组,且 d 较⼩        ②每组关键字的取值范围不⼤,即 r 较⼩        ③数据元素个数 n 较⼤如:内部排序总结:         基本有序:  直接插入(比较最少), 冒泡(趟数最少)6.9 外部排序        数据元素太多,⽆法⼀次全部读⼊内存进⾏排序, 读写磁盘的频率成为衡量外部排序算法的主要因素。示例图:多路归并:        结论: 采⽤多路归并可以减少归并趟数,从⽽减少磁盘I/O(读写)次数。对 r 个初始归并段,做k路归并,则归并树可⽤ k 叉树表示 若树⾼为h,则归并趟数 = h-1 = 。K越大, r越小, 读写磁盘次数越少。(缺点: k越大, 内部排序时间越大)6.9.1 败者树        使⽤k路平衡归并策略,选出⼀个最小元素需要对⽐关键字 (k-1)次,导致内部归并所需时间增加。因此引入败者树。示例图:        结论: 对于 k 路归并,第⼀次构造败者 树需要对⽐关键字 k-1 次 , 有了败者树,选出最⼩元素,只需对⽐关键字次6.9.2 置换-选择排序        使用置换-选择排序可以减少初始化归并段。示意图: 6.9.3 最佳归并树原理图:        注意:对于k叉归并,若初始归并段的数量⽆法构成严格的 k 叉归并树, 则需要补充⼏个⻓度为 0 的“虚段”,再进⾏ k 叉哈夫曼树的构造。示例图: 添加虚段数目: 难点:结束!  !  !注: 以上部分图片素材来自王道数据结构我要的图文并茂关注
03-24
在B树结构中,每个节点最多有m棵子树,但最多只包含m-1个关键字的原因与B树的结构设计密切相关。B树是一种平衡的多路查找树,其主要目的是为了在磁盘等外部存储设备上高效地进行查找、插入和删除操作。为了保证树的平衡性和高效性,B树的节点设计有明确的约束条件。 每个节点包含的关键字数量决定了其子树的数量。具体来说,如果一个节点包含k个关键字,则它最多可以拥有k+1棵子树。这是因为在B树中,关键字用于划分子树,每个关键字对应两个子树的分界。例如,若一个节点包含三个关键字,则它最多可以拥有四个子树。因此,在一棵m阶B树中,一个节点最多可以拥有m棵子树[^4]。 基于这一规则,为了确保一个节点最多拥有m棵子树,它最多只能包含m-1个关键字。这种设计使得每个节点既能保持足够的数据存储能力,又能维持树的平衡性,从而保证查找、插入和删除操作的时间复杂度为对数级别[^1]。 此外,这种设计还确保了B树的每个节点在分裂时能够合理地分配关键字和子树,从而维持树的平衡性。当一个节点的关键字数量超过m-1时,该节点将被分裂成两个节点,并将中间关键字提升到父节点中,以确保每个节点的关键字数量始终在规定的范围内[^5]。 因此,B树中每个节点最多有m棵子树但最多只包含m-1个关键字的设计,是为了维持树的平衡性、提升查找效率,并确保在插入和删除操作时能够合理地进行节点的分裂和合并。 ### 示例代码 以下是一个用于描述B树节点结构的简单Python类,展示了每个节点的关键字数量与子树数量之间的关系: ```python class BTreeNode: def __init__(self, t, leaf): self.t = t # 最小度数 self.keys = [] # 关键字列表 self.children = [] # 子节点列表 self.leaf = leaf # 是否为叶子节点 def is_full(self): return len(self.keys) == 2 * self.t - 1 # 判断节点是否已满 def split(self): # 分裂节点的逻辑 mid = self.t - 1 new_node = BTreeNode(self.t, self.leaf) new_node.keys = self.keys[mid+1:] self.keys = self.keys[:mid] if not self.leaf: new_node.children = self.children[mid+1:] self.children = self.children[:mid+1] return new_node, self.keys.pop() ``` ### 相关问题 1. B树和B+树在关键字数量和子树数量的设计上有哪些区别? 2. B树的高度如何影响查找效率? 3. B树节点分裂的具体过程是怎样的? 4. 为什么B树的每个节点需要满足关键字数量的最小和最大限制? 5. B树的阶数m对树的结构和性能有什么影响?
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值