数据结构_树的深度
中国农业大学_821数据结构_《数据结构》习题(6)

第6章 二叉树与树一、回答题1. 图6-1所示的树的叶子结点、非中端结点、每个结点的度及树的深度各是多少?图6-1 树2. 已知一棵树边的集合表示为:{ ( L, N ), ( G, K ), ( G, L ), ( G, M ), ( B, E ), ( B, F ), ( D, G ), ( D, H ), ( D, I ), ( D, J ), ( A, B ), ( A, C ), ( A, D ) },画出这棵树,并回答以下问题:(1) 树的根结点是哪个?哪些是叶子结点?哪些是非终端结点? (2) 树的度是多少?各个结点的度是多少? (3) 树的深度是多少?各个结点的层数是多少?(4) 对于结点G ,它的双亲结点、祖先结点、孩子结点、子孙结点、兄弟和堂兄弟分别是哪些结点?3. 如果一棵度为m 的树中,度为1的结点数为n 1,度为2的结点数为n 2,……,度为m 的结点数为n m ,那么该树中含有多少个叶子结点?有多少个非终端结点?ABECDFGHJI4. 任意一棵有n 个结点的二叉树,已知有m 个叶子结点,能否证明度为2结点有m-1个?5. 已知在一棵含有n 个结点的树中,只有度为k 的分支结点和度为0的叶子结点,那么该树含有的叶子结点的数目是多少?6. 一棵含有n 个结点的k 叉树,可能达到的最大深度和最小深度各为多少?7. 对于3个结点A 、B 、C ,可以过程多少种不同形态的二叉树?8. 深度为5的二叉树至多有多少个结点?9. 任何一棵二叉树的叶子结点在先序、中序和后序遍历中的相对次序是发生改变?不发生改变?不能确定?10. 设n 、m 为一棵二叉树上的两个结点,在中序遍历时,n 在m 前的条件是什么? 11. 已知某二叉树的后续遍历序列是dabec ,中序遍历序列是debac ,那么它的前序遍历序列是什么?12. 对一棵满二叉树,m 个树叶,n 个结点,深度为h ,则n 、m 和h 之间的关系是什么? 13. 对图6-2(a)和(b)所示的二叉树,它们的经过先序、中序和后序遍历后得到的结点序列分别是什么?画出它们的先序线索二叉树和后序线索二叉树。
数据结构参考答案

简答一.1、已知模式串pat=’ADABBADADA’,写出该模式串的next函数值和nextval值;2、模式匹配算法是在主串中快速寻找模式的一种有效的方法,如果设主串的长度为m,模式的长度为n,则在主串中寻找模式的KMP算法的时间复杂性是多少?如果,某一模式 P=’abcaacabaca’,请给出它的NEXT函数值及NEXT函数的修正值NEXTVAL之值。
3、已知模式串pat=“abaabc”,写出该模式串的next函数值和nextval值;4、给出字符串‘abacabaaad’在KMP算法中的next和nextval数组。
二、(意思对即可,不一定是这种写法)1、数据结构按照逻辑结构分为哪四种结构,说出元素之间的关系?集合:无关系线性结构:一对一树形结构:一对多图形结构:多对多2、图形结构有几种存储结构?分别是什么存储结构?4种。
邻接矩阵,邻接表,十字链表,邻接多重表3、度数为2的树和二叉树有何区别?(1)度为2的树中至少有一个结点的度为2,而二叉树中没有这种要求。
(2)度为2的树不区分左右子树,而二叉树严格区分左右子树。
4、简述栈和队列的特点。
栈:是一种只能在一端进行插入或删除操作的线性表。
“后进先出”队列:是一种仅允许在表的一端进行插入操作,而在表的另一端进行删除操作的受限的线性表“先进先出”三(只是最终的结果,有的题可能需要中间步骤,自己完善一下)1、已知某有向图的顶点集合为{A,B,C,D,E,F},边集合为{〈A,B〉,〈A,C〉,〈A,E〉,〈C,F〉,〈E,D〉},画出该图的邻接表,以它为基写出深度优先、广度优先遍历序列(深度、广度遍历要求从结点A开始)。
深度:A B C F E D广度:A B C E F D2、设无向图G(如右图所示),给出该图的最小生成树上边的集合并计算最小生成树各边上的权值之和。
3、对下图所示的无向图,从顶点1开始,写出该图的深度优先遍历和广度优先遍历。
数据结构树的知识点总结

数据结构树的知识点总结一、树的基本概念。
1. 树的定义。
- 树是n(n ≥ 0)个结点的有限集。
当n = 0时,称为空树。
在任意一棵非空树中:- 有且仅有一个特定的称为根(root)的结点。
- 当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、…、Tm,其中每个集合本身又是一棵树,并且称为根的子树(sub - tree)。
2. 结点的度、树的度。
- 结点的度:结点拥有的子树个数称为结点的度。
- 树的度:树内各结点的度的最大值称为树的度。
3. 叶子结点(终端结点)和分支结点(非终端结点)- 叶子结点:度为0的结点称为叶子结点或终端结点。
- 分支结点:度不为0的结点称为分支结点或非终端结点。
- 除根结点之外,分支结点也称为内部结点。
4. 树的深度(高度)- 树的层次从根开始定义起,根为第1层,根的子结点为第2层,以此类推。
树中结点的最大层次称为树的深度(或高度)。
二、二叉树。
1. 二叉树的定义。
- 二叉树是n(n ≥ 0)个结点的有限集合:- 或者为空二叉树,即n = 0。
- 或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
2. 二叉树的特点。
- 每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
- 二叉树的子树有左右之分,次序不能颠倒。
3. 特殊的二叉树。
- 满二叉树。
- 一棵深度为k且有2^k - 1个结点的二叉树称为满二叉树。
满二叉树的特点是每一层上的结点数都是最大结点数。
- 完全二叉树。
- 深度为k的、有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称之为完全二叉树。
完全二叉树的叶子结点只可能在层次最大的两层上出现;对于最大层次中的叶子结点,都依次排列在该层最左边的位置上;如果有度为1的结点,只可能有一个,且该结点只有左孩子而无右孩子。
三、二叉树的存储结构。
1. 顺序存储结构。
- 二叉树的顺序存储结构就是用一组地址连续的存储单元依次自上而下、自左至右存储完全二叉树上的结点元素。
二叉树操作输出深度结点数叶结点数递归

二叉树操作输出深度结点数叶结点数递归二叉树是一种常用的数据结构,在计算机科学中广泛应用。
二叉树既能够被顺序存储,也能够被链式存储。
本文将介绍如何对二叉树进行操作,包括输出深度、结点数、叶结点数,并给出递归算法的实现。
1.二叉树的深度二叉树的深度是指从根结点到最远叶子结点的最长路径上的结点数。
要输出二叉树的深度,可以使用递归算法。
递归算法的思路是,当二叉树为空时,深度为0;否则,深度为左子树和右子树深度的最大值加1递归实现深度的伪代码如下:```int depth(Node* root)if (root == nullptr)return 0;}int left_depth = depth(root->left);int right_depth = depth(root->right);return std::max(left_depth, right_depth) + 1;```2.二叉树的结点数二叉树的结点数是指二叉树中所有结点的总数。
要输出二叉树的结点数,同样可以使用递归算法。
递归算法的思路是,当二叉树为空时,结点数为0;否则,结点数为左子树结点数加右子树结点数再加1递归实现结点数的伪代码如下:```int node_count(Node* root)if (root == nullptr)return 0;}int left_count = node_count(root->left);int right_count = node_count(root->right);return left_count + right_count + 1;```3.二叉树的叶结点数二叉树的叶结点是指没有子结点的结点。
要输出二叉树的叶结点数,同样可以使用递归算法。
递归算法的思路是,当二叉树为空时,叶结点数为0;当二叉树只有一个结点时,叶结点数为1;否则,叶结点数为左子树叶结点数加右子树叶结点数。
c语言实现二叉树的四种遍历和求深度与叶子个数

c语言实现二叉树的四种遍历和求深度与叶子个数二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。
在C语言中,我们可以使用指针来实现二叉树的操作。
本文将介绍四种常见的二叉树遍历方式,以及如何求解二叉树的深度和叶子节点个数。
首先,我们需要定义一个二叉树节点的结构体,包含一个数据域和两个指针域,分别指向左子节点和右子节点。
代码如下:```cstruct TreeNode {int data;struct TreeNode* left;struct TreeNode* right;};```接下来,我们可以实现二叉树的四种遍历方式:前序遍历、中序遍历、后序遍历和层序遍历。
前序遍历是指先访问根节点,然后递归地遍历左子树和右子树。
代码如下:```cvoid preorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}printf("%d ", root->data);preorderTraversal(root->left);preorderTraversal(root->right);}```中序遍历是指先递归地遍历左子树,然后访问根节点,最后递归地遍历右子树。
代码如下:```cvoid inorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}inorderTraversal(root->left);printf("%d ", root->data);inorderTraversal(root->right);}```后序遍历是指先递归地遍历左子树和右子树,最后访问根节点。
代码如下:```cvoid postorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}postorderTraversal(root->left);postorderTraversal(root->right);printf("%d ", root->data);}```层序遍历是按照树的层次逐层遍历节点。
数据结构填空练习题

数据结构填空练习题数据结构填空练习题一1. 通常从四个方面评价算法的质量:_________、_________、_________和________。
2.一个算法的时间复杂度为(n3+n2log2n+14n)/n2,其数量级表示为________。
3.假定一棵树的广义表表示为A(C,D(E,F,G),H(I,J)),则树中所含的结点数为__________个,树的深度为___________,树的度为_________。
4. 后缀算式9 2 3 +- 10 2 / -的值为__________。
中缀算式(3+4X)-2Y/3对应的后缀算式为_______________________________。
5. 若用链表存储一棵二叉树时,每个结点除数据域外,还有指向左孩子和右孩子的两个指针。
在这种存储结构中,n个结点的二叉树共有________个指针域,其中有________个指针域是存放了地址,有________________个指针是空指针。
6. 对于一个具有n个顶点和e条边的有向图和无向图,在其对应的邻接表中,所含边结点分别有_______个和________个。
7. AOV网是一种___________________的图。
8. 在一个具有n个顶点的无向完全图中,包含有________条边,在一个具有n个顶点的有向完全图中,包含有________条边。
9. 假定一个线性表为(12,23,74,55,63,40),若按Key % 4条件进行划分,使得同一余数的元素成为一个子表,则得到的四个子表分别为____________________________、___________________、_______________________和__________________________。
10. 向一棵B_树插入元素的过程中,若最终引起树根结点的分裂,则新树比原树的高度___________。
数据结构3(树形结构)

递归定义 二叉树是由“根节点”、“左子树”和“右子树” 三部分构成,则遍历二叉树的操作可分解 为“访问根节点”、“遍历左子树”和“遍历右 子树”三个子操作。 因此,不难得到三种遍历的递归定义:
– 先序遍历:访问根节点;先序遍历左子树;先序遍历 右子树; – 中序遍历:中序遍历左子树;访问根节点;中序遍历 右子树; – 后序遍历:后序遍历左子树;后序遍历右子树;访问 根节点。
二叉树的存储结构:链式存储结构(1)
typedef struct BiTNode { Lchild data Rchild ElemType data; struct BiTNode *Lchild, *Rchild; // 左、右孩子指针 } *BiTree;
二叉树的存储结构:链式存储结构(2) 上面链式结构只能从根向下找,无法直接获 得节点的父节点
– 启示:给定任意两种遍历序列,唯一确定这棵树。
先序遍历:递归伪代码
template<class T> void BinaryTree<T>::PreOrder(BinaryTreeNode<T>*root){ if(root!=NULL){ Visit(root); //访问根节点 PreOrder(root->leftchild()); //访问左子树 PreOrder(root->rightchild());//访问右子树 } } 注:Visit(root)是个抽象操作,实际上,“访问”可以在该节点 上做任何操作。
中序遍历:递归伪代码
template<class T> void BinaryTree<T>::PreOrder(BinaryTreeNode<T>*root){ if(root!=NULL){ PreOrder(root->leftchild()); //访问左子树 Visit(root); //访问根节点 PreOrder(root->rightchild());//访问右子树 } }
完全二叉树的深度计算公式

完全二叉树的深度计算公式完全二叉树是数据结构中一个很重要的概念。
对于完全二叉树的深度计算,是有特定公式的。
先来说说啥是完全二叉树。
想象一下,一棵大树,它的每一层都被填得满满的,除了最后一层。
而且最后一层的叶子节点,都是从左边开始依次排列的。
这就像是排队,整整齐齐,一个不落。
那完全二叉树的深度咋算呢?公式是:$depth = \lfloor log_2{n}\rfloor + 1$ ,这里的 $n$ 表示完全二叉树的节点个数。
我给您举个例子啊。
比如说有一棵完全二叉树,它一共有 15 个节点。
那咱们先算 $\lfloor log_2{15} \rfloor$ ,这约等于 3 ,再加上 1 ,所以这棵完全二叉树的深度就是 4 。
为啥要有这个公式呢?这就好比咱们盖房子,得知道盖多高心里才有数。
计算完全二叉树的深度,能帮助我们更好地理解和处理这棵“数据之树”。
我记得之前有一次,在给学生们讲这个知识点的时候,有个学生就特别迷糊,怎么都搞不明白。
我就带着他,一步一步地画,一个节点一个节点地数。
我跟他说:“你看啊,这就像咱们搭积木,一层一层来,每一层都有它的规律。
” 最后这孩子恍然大悟,那种成就感,真的让人特别开心。
再回到这个公式,其实理解起来也不难。
$log_2{n}$ 表示的就是以2 为底,$n$ 的对数。
这个对数的值,就相当于完全二叉树去掉最后一层,前面那些层填满的情况下的层数。
再加上 1 ,就是包括最后一层的总深度啦。
在实际应用中,比如在计算机编程里,要优化数据存储和搜索,完全二叉树就大有用处。
通过计算它的深度,能更高效地安排数据的位置,提高程序的运行效率。
总之,完全二叉树的深度计算公式虽然看起来有点复杂,但只要多琢磨琢磨,多练习练习,就一定能掌握。
就像解决生活中的难题一样,只要有耐心,有方法,都能迎刃而解!希望大家都能轻松搞定这个知识点,让数据结构不再成为学习路上的“拦路虎”。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
建立树的存储结构
求树的深度
*/
1.源程序:
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct CSNode{ //树
char data;
struct CSNode *firstchild, *nextsibling;
}CSNode;
typedef struct {
CSNode* *elem;
int front;
int rear;
}LinkQueue;
void InitQueue(LinkQueue &Q){
Q.elem=(CSNode **)malloc(MAX*sizeof(CSNode));
Q.front=Q.rear=0;
}
CSNode* EnQueue(LinkQueue &Q,CSNode *p)
{
if(Q.front==Q.rear) Q.elem[Q.front]=p;
Q.rear++;
Q.elem[Q.rear]=p;
return p;
}
CSNode* DeQueue(LinkQueue &Q,CSNode *p)
{
p=Q.elem[Q.front];
Q.front++;
return p;
}
CSNode* GetHead(LinkQueue Q,CSNode *p){
if(Q.rear != Q.front) p=(Q.elem[Q.front]);
else p=NULL;
return p;
int TreeDepth(CSNode *T) {
if(!T) return 0;
else {
int h1 = TreeDepth( T->firstchild );
int h2 = TreeDepth( T->nextsibling);
return( (h1+1>h2)? h1+1: h2);
}
}
CSNode* GetTreeNode(char c){
CSNode *C;
C=(CSNode *)malloc(sizeof(CSNode));
C->data=c;
C->firstchild=NULL;
C->nextsibling=NULL;
return C;
}
void Preorder(CSNode *T) //先序遍历
{
if (T){
printf("%c\t",T->data); // 访问结点
Preorder(T->firstchild); // 遍历左子树
Preorder(T->nextsibling); // 遍历右子树
}
}
CSNode * CreatTree( CSNode *T ) {
char ch,fa;
LinkQueue Q;
InitQueue(Q);
CSNode *p,*r,*s;
p=(CSNode *)malloc(sizeof(CSNode));
r=(CSNode *)malloc(sizeof(CSNode));
s=(CSNode *)malloc(sizeof(CSNode));
printf("请输入树的序列:\n");
scanf("%c %c",&fa,&ch);
while( ch!='0'){
p = GetTreeNode(ch); // 创建结点
p=EnQueue(Q, p); // 指针入队列
if (fa == '#') T = p; // 所建为根结点
else {
s=GetHead(Q,s); // 取队列头元素(指针值)
while (s->data != fa ) { // 查询双亲结点
s=DeQueue(Q,s);
s=GetHead(Q,s);
}
if (!(s->firstchild)) {
s->firstchild = p;
r = p;
} // 链接第一个孩子结点
else {
r->nextsibling = p;
r = p;
} // 链接其它孩子结点
}
getchar();
scanf("%c %c",&fa,&ch);
}
Preorder(T);
printf("\n");
return T;
}
void main()
{
CSNode *T;
T=(CSNode *)malloc(MAX*sizeof(CSNode));
T=CreatTree(T);
int depth;
depth=TreeDepth(T);
printf("该树的深度为:%d\n",depth);
}
2.运行窗口截图:。