二叉树的建立与遍历

32 篇文章 1 订阅
6 篇文章 0 订阅

一、原题

二叉树的建立与遍历(binary-tree)

题目描述

给出一棵二叉树,分别输出先序、中序、后序遍历结果。

输入

第1行:结点数n(1<=n<=100)
以下若干行,每行3个整数,分别表示父结点、左孩子、右孩子。若没有孩子,对应的整数为0.

输出

第1行:树根
第2行:先序遍历结果,数字间用1个空格分开。
第3行:中序遍历结果,数字间用1个空格分开。
第4行:后序遍历结果,数字间用1个空格分开。

样例输入

8
1 2 4
2 0 0
4 8 0
3 1 5
5 6 0
6 0 7
8 0 0
7 0 0

样例输出

3
3 1 2 4 8 5 6 7
2 1 8 4 3 6 7 5
2 8 4 1 7 6 5 3

二、分析

这道题需要用到二叉树的知识去做,涉及到的知识点有先序遍历、中序遍历和后序遍历。首先,这道题要用结构体储存。

struct node{
    int fath;//父亲
    int lchd,rchd;//左儿子和右儿子
}tree[105];

要读入二叉树,在读的过程中,要标记好父亲、左儿子和右儿子。

那么怎么找根节点?

从样例可以看出,根节点3不是任何人的儿子也就是说,根节点的父亲为0,一个for循环就能找到了。

for(int i=1;i<=n;i++)
    if(tree[i].fath==0)
        root=i;//找到根节点

那么如何遍历?

可见每个节点都要被访问,那么当这个节点被访问时,就要考虑输出的先后。这就是先序、中序和后序遍历的区别。

void first(int x){//先序遍历结果
    if(!x)//非零
        return;
    cout<<x<<" ";
    first(tree[x].lchd);
    first(tree[x].rchd);
}
void mid(int x){//中序遍历结果
    if(!x)//非零
        return;
    mid(tree[x].lchd);
    cout<<x<<" ";
    mid(tree[x].rchd);
}
void last(int x){//后序遍历结果
    if(!x)//非零
        return;
    last(tree[x].lchd);
    last(tree[x].rchd);
    cout<<x<<" ";
}

以下是代码:

三、源代码

#include<iostream>
#include<cstdio>
using namespace std;
int n,root;
struct node{
    int fath;//父亲
    int lchd,rchd;//左儿子和右儿子
}tree[105];
void print(){//读入二叉树
    for(int i=1;i<=n;i++){
        int x,y,z;
        cin>>x>>y>>z;
        tree[y].fath=x;//找到父亲
        tree[z].fath=x;//找到父亲
        tree[x].lchd=y;//找到左儿子
        tree[x].rchd=z;//找到右儿子
    }
    for(int i=1;i<=n;i++)
        if(tree[i].fath==0)
            root=i;//找到根节点
    cout<<root<<endl;
}
void first(int x){//先序遍历结果
    if(!x)//非零
        return;
    cout<<x<<" ";
    first(tree[x].lchd);
    first(tree[x].rchd);
}
void mid(int x){//中序遍历结果
    if(!x)//非零
        return;
    mid(tree[x].lchd);
    cout<<x<<" ";
    mid(tree[x].rchd);
}
void last(int x){//后序遍历结果
    if(!x)//非零
        return;
    last(tree[x].lchd);
    last(tree[x].rchd);
    cout<<x<<" ";
}
int main()
{
    cin>>n;
    print();
    first(root);
    cout<<endl;
    mid(root);
    cout<<endl;
    last(root);
    cout<<endl;
}

不允许有多的空格版:

#include<iostream>
#include<cstdio>
using namespace std;
int n,root;
bool flag;
struct node{
    int fath;//父亲
    int lchd,rchd;//左儿子和右儿子
}tree[105];
void print(){//读入二叉树
    for(int i=1;i<=n;i++){
        int x,y,z;
        cin>>x>>y>>z;
        tree[y].fath=x;//找到父亲
        tree[z].fath=x;//找到父亲
        tree[x].lchd=y;//找到左儿子
        tree[x].rchd=z;//找到右儿子
    }
    for(int i=1;i<=n;i++)
        if(tree[i].fath==0)
            root=i;//找到根节点
    cout<<root<<endl;
}
void first(int x){//先序遍历结果
    if(!x)//非零
        return;
    if(!flag){cout<<x;flag=1;}
    else
        cout<<" "<<x;
    first(tree[x].lchd);
    first(tree[x].rchd);
}
void mid(int x){//中序遍历结果
    if(!x)//非零
        return;
    mid(tree[x].lchd);
    if(!flag){cout<<x;flag=1;}
    else
        cout<<" "<<x;
    mid(tree[x].rchd);
}
void last(int x){//后序遍历结果
    if(!x)//非零
        return;
    last(tree[x].lchd);
    last(tree[x].rchd);
    if(!flag){cout<<x;flag=1;}
    else
        cout<<" "<<x;
}
int main()
{
    cin>>n;
    print();
    first(root);
    cout<<endl;
    flag=0;
    mid(root);
    cout<<endl;
    flag=0;
    last(root);
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值