二叉树的构建与遍历(链表法)

二叉树作为基础数据结构,其构建与遍历可以说是一名程序员的基本功,更是一名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");
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值