二叉树作为基础数据结构,其构建与遍历可以说是一名程序员的基本功,更是一名ACMer的应烂熟于心的知识。
其中建立二叉树的方法主要有用链表建立和用数组建立,本篇文章我们先来介绍链表法建立二叉树。
相对于用数组建立二叉树来说,用链表建立二叉树具有节省空间,简介明了、直观的特点,因此在大部分情况下推荐使用链表法建树。但如果查询树上的一个节点,数组法就比较简介,两种方法各有千秋,文无定法,适者为尊。
对于遍历来说,树的遍历基本有三种,为先序遍历(根左右),中序遍历(左根右),后序遍历(左右根)。当我们建好树后,以上三种遍历都可以用递归方法实现,实现较为简单,非编程初学者看代码即可领悟,这里不在赘述。
我们以一道题为例,来讲解二叉树的构建与遍历。
【问题描述】
根据输入提示,构建二叉树。本题目中,对所有节点进行编号
【输入形式】
第一行整数m,表示二叉树中共有m个非空节点
第二行m个整数,表示编号节点对应的value值,编号从1到m
后面一共m行,表示编号节点的左右子节点编号,0表示对应位置的子节点不存在
【输出形式】
按先序输出格式输出二叉树
【样例输入】
8
10 4 3 9 2 5 6 7
1 2 3
2 0 4
3 5 6
4 7 0
5 0 0
6 0 8
7 0 0
8 0 0
【样例输出】
10 4 9 6 3 2 5 7
分析:
本题就是一道考察建树及遍历的基础题,无任何其他内容。
解析:
用链表建树,首先需掌握基本链表操作,这里所指链表并非是C++中STL自带容器,本人一贯认为STL虽然可以减少很多工作量,但对于初学者来说,自己手写代码是个很重要的过程,在之前的OI比赛中(近期情况并不了解),STL库函数是禁用的。所以对基础知识不熟者,需自行查书或自行百度。
其实建树并没有什么可讲的,不涉及算法,下面我就用加注释的方法解释建树和遍历的过程,大家在理解后可自行整理为属于自己风格的模板,留作自己的东西
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
struct Btree{
int num; //节点编号
struct Btree *Lchild; //左子树
struct Btree *Rchild; //右子树
};
struct data{
int left; //左孩子节点编号
int right; //右孩子节点编号
};
int value[110]; //节点的值
data tree[110]; //用作存储读入
Btree *CreateTree(int root)
{
Btree *t;
t = (Btree*) malloc (sizeof(Btree)); // 申请新节点空间
t->num = root; //编号赋值
if(tree[root].left == 0) t->Lchild=NULL;
else t->Lchild = CreateTree(tree[root].left); //去建左子树
if(tree[root].right == 0) t->Rchild=NULL;
else t->Rchild = CreateTree(tree[root].right); //去建右子树
return t;
}
void pre(Btree *&t)
{
if(t)
{
printf("%d ",value[t->num]); //根
pre(t->Lchild); //左
pre(t->Rchild); //右
}
}
void middle(Btree *&t)
{
if(t)
{
middle(t->Lchild);
printf("%d ",value[t->num]);
middle(t->Rchild);
}
}
void back(Btree *&t)
{
if(t)
{
back(t->Lchild);
back(t->Rchild);
printf("%d ",value[t->num]);
}
}
int main()
{
int m;
scanf("%d",&m);
for(int i = 1;i <= m;i++)
scanf("%d",&value[i]);
for(int i = 1;i <= m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
tree[a].left = b;tree[a].right = c;
}
Btree *t; //建树
//t = (Btree *) malloc (sizeof(Btree))
t = CreateTree(1); //树根
pre(t);printf("\n");
middle(t);printf("\n");
back(t);printf("\n");
}