二叉树(Binary Tree)是 n( n >= 0 ) 个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和又子树的二叉树组成;
每个结点最多有两棵子树,所以二叉树中不存在度大于 2 的结点;(注意:不是都需要两棵子树,而是最多可以是两棵,没有子树或者有一颗子树也都是可以的;)
左子树和右子树是有顺序的,次序不能颠倒;
即使树种某结点只有一颗子树,也要区分他是左子树还是右子树;
- 空二叉树
- 只有一个根结点
- 根结点只有左子树
- 根结点只有右子树
-根结点既有左子树又有右子树
在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树;
对一棵具有 n 个结点的二叉树按层序编号,如果编号为 i ( 1 <= i <= n ) 的结点与同样深度的满二叉树中编号为 i 的结点位置完全相同,则这棵二叉树就被称为 -> 完全二叉树;
- 叶子结点只能出现在最下两层
- 最下层的叶子一定集中在左部连续位置
- 倒数第二层,若有叶子结点,一定都在右部连续位置
- 如果结点度为 1 ,则该结点只有左孩子
- 同样结点树的二叉树,完全二叉树的深度最小
注意:满二叉树一定是完全二叉树,但是完全二叉树不一定是满二叉树;
补充一点:在二叉树的第 i 层上最多有 2 ^ ( i - 1 ) 个结点;
- 树结构在计算中的存储形式很多,可谓天马行空任你创造,只要能够按照要求完成任务即可;
- 在前边的演示中,我们发掘很难丹丹只用顺序存储结构或者链式存储结构来存放;
- 但是二叉树是一种特殊的树,由于他的特殊性,使得用顺序存储结构或者李娜是存储结构都能简单的实现;
- 二叉树的顺序存储结构就是用一维数组存储二叉树中的各个结点,并且结点的存储位置能体现结点之间的逻辑关系;
这下能看出完全二叉树的优越性了吧?由于他的严格定义,在数组直接能表现出逻辑结构;
但是这种存储方式也有缺陷,例如当我们需要存储一棵右斜二叉树,只有三个结点,这时候就需要用大量空间存储的空去表示该结点处没有结点,十分的浪费资源;
既然顺序存储方式的适用性不强,那么我们就要考虑链式存储结构了;二叉树的存储结构按照国际惯例来说,一般也是采用链式存储结构的;
二叉树每个结点最多有两个孩子,所以为他设计一个数据域,两个指针域是比较合适的想法,我们称这样的链表叫做二叉链表 ->
二叉树的遍历( traversing binary tree )是指从根结点出发,按照某种 次序 依次 访问 二叉树中所有结点,使得每个结点被访问一次且仅被访问一次;
二叉树的遍历次序不同于线性结构,线性结构最多也就是分为顺序、循环、双向等简单的遍历方式;
树的结点之间不存在唯一的前驱和后继这样的关系,在访问一个结点后,下一个被访问的结点面临着不同的选择;
- 前序遍历
- 中序遍历
- 后序遍历
-层序遍历
- 若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树;
前序遍历的顺序为 : A B D H I E J C F K G
- 若树为空,则空操作返回,否则从根结点开始(注意:并不是先访问根结点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树;
中序遍历的顺序为 : H D I B E J A F K C G
- 若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后访问根结点;
后序遍历的顺序为 : H I D J E B K F G C A
层序遍历的顺序比较好记 就是 -> A B C D E F G H I J K
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
typedef char ElemType;
typedef struct BitNode {
int data;
struct BitNode* leftChild;
struct BitNode* rightChild;
}BitNode;
//创建一棵二叉树,约定用户遵照前序遍历的方式输入数据
void createBiTree(BitNode** Node) {
char c = 0;
scanf("%c",&c);
if (c == ' ') {
*Node = NULL;
}
else {
BitNode* tmp = (BitNode*)malloc(sizeof(BitNode));
assert(tmp != NULL);
*Node = tmp;
(*Node)->data = c;
createBiTree(&((*Node)->leftChild));
createBiTree(&((*Node)->rightChild));
}
}
//访问二叉树结点的具体操作
void visit(char c,int level) {
printf("%c 位于第 %d 层\n",c,level);
}
//前序遍历二叉树
void preOrderTraverse(BitNode* Node,int level) {
if (Node) {
visit(Node->data,level);
preOrderTraverse(Node->leftChild,level + 1);
preOrderTraverse(Node->rightChild,level + 1);
}
}
int main() {
int level = 1;
BitNode* Node = NULL;
createBiTree(&Node);
preOrderTraverse(Node,level);
return 0;
}
输入 -> AB空格E空格空格CF空格空格空格
输出如下图所示 ->