二叉树的相关知识

二叉树

概念

二叉树是n(n>=0)个节点的有限集合,该集合或者为空集(即空二叉树),或者有一个根节点和俩棵互不相交的,分别称为根节点的左右子树组成,

如图所示:
在这里插入图片描述
Note:
1.二叉树的每个结点的度<=2
2.左右子树是有顺序的,次序不能够颠倒。
下面是俩棵不同的二叉树
在这里插入图片描述

二叉树的性质:

1.在二叉树的第n层中,至多有2^(n-1)个结点(n>0)
2.深度为k的二叉树至多有2^K-1个结点(k>=1)
3.对于任何一个二叉树T ,如果其终端结点数(叶子节点)为n0,度为2的结点数为n2
则 n0 =n2+1
4.具有n个结点的完全二叉树的深度为
在这里插入图片描述
5.如果对一颗有n个结点的完全二叉树(其深度为以上图所示)的结点按层序编号,对于任一节点i(1<=i<=n)有一下性质:

如果i=1,则节点i是二叉树的跟,无双亲;如果i>1,则其双亲是节点|_ i/2 _|
如果2i>n,则节点i 无左孩子(节点i为叶子节点); 否则其左孩子是结点2i
如果2i+1>n ,则结点i无右孩子,否则其右孩子是结点2i+1

特殊的二叉树:

满二叉树

在一棵二叉树中,如果所有的分支结点都存在左右子树,并且所有叶子结点都存在同一层,这样的数称之为满二叉树。
如图所示
在这里插入图片描述

满二叉树的特点

叶子只能出现最下一层
非叶子节点的度一定是2
在同样深度的二叉树中,满二叉树的结点个数一定是最多,同时叶子结点也是最多

完全二叉树

对一颗具有n个节点的二叉树按层序进行编号,如果编号为i(1<=i<=n)的结点与同样深度的满二叉树中编号为i的结点位置完全相同,则这颗二叉树称为完全二叉树

在这里插入图片描述

完全二叉树特点

叶子结点只能出现最下2层
最下层的叶子一定集中在左部连续位置
倒数第二层,如有叶子结点,一定都在右部连续位置
如果结点度为1,则该节点只有左孩子
同样的结点树的二叉树,完全二叉树的深度最小。

满二叉树一定是完全二叉树,但完全二叉树不一定是满二叉树

一道关于二叉树的例题:
如果一个完全二叉树的结点总数为349个,求叶子结点的个数。

由二叉树的性质知:n0=n2+1,将之带入349=n0+n1+n2中得:349=n1+2n2+1,因为完全二叉树度为1的结点个数要么为0,要么为0,那么就把n1=0或者1都代入公式中,很容易发现n1=1才符合条件。
。所以算出来n2=174,所以叶子结点个数n0=n2+1=175。

由此我们可以推断:

如果一棵完全二叉树的结点总数为n,那么叶子结点等于n/2(当n为偶数时)或者(n+1)/2(当n为奇数时)

二叉树的遍历

二叉树的遍历主要有3种方式,分别是前序遍历,中序遍历,以及后序遍历

前,中 , 后,主要是针对根节点来说的。

主要是靠递归进行实现的
在这里插入图片描述

对于以上图:
前序遍历: A B D E H C F I G J
中序遍历 : D B H E A F I C G J
后序遍历: D H E B I F J G C A

### 二叉树的概念 二叉树是一种重要的非线性数据结构,其中每个节点最多有两个子节点:左子节点和右子节点。这种特性使得二叉树非常适合用于表示层次关系,并且可以高效地执行插入、删除和查找操作。 #### 特殊类型的二叉树 - **满二叉树**:除了最后一层外,每一层上的所有节点都有两个子节点。 - **完全二叉树**:除最后一层外,其他各层的节点数都达到最大值;并且最下面一层的节点全部集中在该层最左边的位置上。 - **平衡二叉树**:对于任意节点而言,其左右子的高度差不超过1[^3]。 ### C语言中的二叉树定义 在C语言中,通常通过结构体来定义二叉树节点: ```c typedef struct TreeNode { char data; struct TreeNode* lchild; struct TreeNode* rchild; } BiTree, *BiTreeNode; ``` 这段代码声明了一个名为`TreeNode`的结构体类型,它包含了三个成员变量:存储节点值的`data`字段以及指向左右孩子的指针`lchild`和`rchild`。 ### 使用先序遍历来创建二叉树 给定一个字符串序列作为输入,可以通过递归的方式按照先序方式构建一棵二叉树。当遇到特定字符(如'#')时表示当前分支为空,则返回NULL终止此路径下的进一步处理。 ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树节点结构 typedef struct TreeNode { char data; struct TreeNode* lchild; struct TreeNode* rchild; } BiTree; // 创建新节点函数 BiTree* CreateNode(char val) { BiTree* newNode = (BiTree*)malloc(sizeof(BiTree)); if (!newNode) exit(-1); newNode->data = val; newNode->lchild = newNode->rchild = NULL; return newNode; } // 先序创建二叉树 BiTree* CreateBiTree() { printf("Please input node element, and '#' == 'NULL': "); getchar(); char ch; scanf("%c", &ch); if (ch == '#') return NULL; BiTree* T = CreateNode(ch); T->lchild = CreateBiTree(); // 左子 T->rchild = CreateBiTree(); // 右子 return T; } ``` 上述程序实现了基于用户交互式的二叉树构造过程,在实际应用中可以根据具体需求调整读取逻辑以适应不同的应用场景[^2]。 ### 层次遍历算法 为了能够逐层访问整棵二叉树并打印出各个节点的信息,这里提供了一种利用队列辅助完成的方法——广度优先搜索(BFS),即所谓的“按层遍历”。 ```c void LevelOrderTraversal(BiTree* root) { if (!root) return; BiTree* queue[100]; // 假设最大深度不会超过100 int front = 0, rear = 0; queue[rear++] = root; while(front != rear){ BiTree* current = queue[front++]; printf("%c ", current->data); if(current->lchild!=NULL) queue[rear++]=current->lchild; if(current->rchild!=NULL) queue[rear++]=current->rchild; } } ``` 在这个例子中,使用数组模拟了FIFO行为的简单队列机制来进行节点间的传递工作[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值