更一波二叉树吧,balabalalala......q_q..(蒟蒻飘过~~~~)
---------------------------------------------------------------------------------------------------------------------------------
目录
二叉树的概念:
1:对于每一个节点,它拥有的子节点个数称之为这个节点的度。
解释:根A的度为2,因为根A有1跟2两个节点
2:因为每个二叉树的节点最多只会有两个子节点,它的子节点一般会被称为左右儿子,两个树会被称为左右子树。当然,左右儿子甚至根节点本身会缺失(如果一个节点都没有则可以称为空二叉树)
解释:
3:具有相同节点深度的二叉树节点处于同一层。
解释:
附图:现实生活中的二叉树
看吧,这就是二叉树!只不过在数据结构中,我们的二叉树是倒过来的。
附图:(很形象吧...xixixi~)
二叉树的类型:
1:完全二叉树:除了最后一层外,其他层的节点个数全满,而且最后一层的节点从左到右排满直到最后一个节点。
2:满二叉树:所有层的节点全满。 结论:满二叉树的节点个数:-1 (n:层数)
二叉树的建立:
数组通用树的建立方法:(这里以题的形式加以理解)
题目描述:给一棵n个节点的二叉树,节点编号为1-n,二叉树的根为1号节点,建立一个二叉树
样例输入:
样例输入解释:第i行代表第i个节点的左右儿子,比如第一行的0,2,代表节点1的左儿子没有,右儿子为2.
//#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;
const int N=520;
int n;
struct TreeNode{//结构体+数组 存树
int l,r,fa;//分别代表 左儿子,右儿子,父亲节点
}a[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y;//x:左儿子 y:右儿子
scanf("%d%d",&x,&y);
if(x) a[i].l=x,a[x].fa=i;//如果左儿子存在,就建立节点
if(y) a[i].r=y,a[y].fa=i;//如果左儿子存在,就建立节点
}
for(int i=1;i<=n;i++){
printf("第%d个节点的左子树:%d 右子树:%d\n",i,a[i].l,a[i].r);
}
}
以上是二叉树的数组形式的普遍建立方法,但是完全二叉树还有个特殊的构造方法!
那就是只用一个数组就可以实现这种树的建立:
解释:完全二叉树由于它的性质,就可以用数组来建立。一般会以数组的【1】位置为根节点建议二叉树;数组的【t】位置的左儿子和右儿子对应的位置分别为【2t】和【2t+1】
数组建立完全二叉树的方法:
二叉树的遍历:1:前序遍历 2:中序遍历 3:后序遍历
1:前序遍历
(口诀:根左右):从根开始,先遍历左子树,再遍历右子树
图解:注:红色代表遍历方向,绿色代表回溯方向
前序遍历结果:1 2 4 5 3 6
代码:
//前序遍历:根左右
void pre(int t){
printf("%d ",t);//输出根
if(a[t].l) pre(a[t].l);//遍历左子树
if(a[t].r) pre(a[t].r);//遍历右子树
}
2:中序遍历
(口诀:左根右):从左子树开始,遍历根,再遍历右子树
图解:注:红色代表遍历方向,绿色代表回溯方向
中序遍历结果:4 2 5 1 6 3
代码:
void mid(int t){
if(a[t].l) mid(a[t].l);//遍历左子树
printf("%d ",t);//输出根
if(a[t].r) mid(a[t].r);//遍历右子树
}
3:后序遍历
(口诀:左右根):从左子树开始,遍历右子树,再遍历根
图解:注:红色代表遍历方向,绿色代表回溯方向
后序遍历结果:4 5 2 6 3 1
代码:
void last(int t){
if(a[t].l) last(a[t].l);//遍历左子树
if(a[t].r) last(a[t].r);//遍历右子树
printf("%d ",t);//输出根
}
总代码:
#include<stdio.h>
using namespace std;
const int N=520;
int n;
struct Node{
int l,r,fa;
}a[N];
void pre(int t){
printf("%d ",t);
if(a[t].l) pre(a[t].l);
if(a[t].r) pre(a[t].r);
}
void mid(int t){
if(a[t].l) mid(a[t].l);
printf("%d ",t);
if(a[t].r) mid(a[t].r);
}
void last(int t){
if(a[t].l) last(a[t].l);
if(a[t].r) last(a[t].r);
printf("%d ",t);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y;
scanf("%d%d",&x,&y);
if(x) a[i].l=x,a[x].fa=i;
if(y) a[i].r=y,a[y].fa=i;
}
printf("前序遍历:");pre(1);printf("\n");
printf("前序遍历:");mid(1);printf("\n");
printf("前序遍历:");last(1);printf("\n");
}
特殊的遍历方式:层序遍历
这里就简要的讲一下就行了,也很简单,其遍历方式就是一层一层的遍历,不用讲究先后顺序,直至遍历最后一层为止。
以上就是本蒟蒻的二叉树基础的全部内容啦,(欢迎大佬三连+关注) 00.00