实验4 二叉树、树、森林——实验及提升训练

第1关:二叉树的创建及遍历输出

任务描述

本关任务:完成二叉树的创建及遍历输出。

相关知识

为了完成本关任务,你需要掌握:

如何创建一棵二叉树;
如何遍历二叉树并输出。

扩充二叉树

在这里插入图片描述

遍历二叉树(二叉树的周游)

在这里插入图片描述
假设有二叉树如下图所示:
在这里插入图片描述
则先根遍历得到的结点序列是: ABDCEGFHI;
中根遍历得到的结点序列是: DBAEGCHFI;
后根遍历得到的结点序列是: DBGEHIFCA。

如何存储一棵二叉树

1.顺序存储法
在这里插入图片描述
2.链式存储法
除了存储结点本身的数据外,再设置两个指针字段:lchild 和 rchild,分别存放结点的左孩子结点和右孩子结点的位置。
数据结构可定义如下:

typedef struct node
{
char data; //存储结点的数据
struct node *lchild,*lchild ;
}BiTreeNode, *BiTree;
*

编程要求

根据提示,在右侧编辑器Begin-End处补充代码,完成创建一棵二叉树,并输出该二叉树的先根、中根、后根遍历结果。

测试说明

平台会对你编写的代码进行测试:
在这里插入图片描述
测试输入:ABD###CE#G##FH##I##;
预期输出:
A B D C E G F H I
D B A E G C H F J
D B G E H I F C A
在这里插入图片描述
测试输入:AB##CE#G###;
预期输出:
A B C E G
B A E G C
B G E C A
开始你的任务吧,祝你成功!
代码:

#include <iostream>
using namespace std;

typedef char DataType;

//二叉树结点定义 
struct node
{
    DataType data; //存放结点数据 
    struct node* lchild, * rchild; //左右孩子指针 
};
typedef struct  node  BiTree;
typedef struct  node* ptree;

//函数可直接使用,功能:输出结点数据
void print(DataType d)
{
    cout << d << " ";
}

/*
函数名:createBiTree
函数功能:创建二叉树,并返回二叉树的根结点指针
参数:无
返回值:二叉树的根结点指针
*/
BiTree* createBiTree() {
    //请在此处填写代码,完成创建二叉树并返回二叉树根结点指针的功能    
    /*-------begin--------*/
    char ch;
    ptree T;
    cin >> ch;
    if (ch == '#')
        T = NULL;
    else{
        T = new struct node;
        T->data = ch;
        T->lchild = createBiTree();
        T->rchild=createBiTree();
    }
    return T;

    /*-------end--------*/
}

/*
函数名:preOrder
函数功能:先根遍历二叉树
参数:二叉树根结点指针
返回值:无
*/
void preOrder(BiTree* T)
{
    //请在此处填写代码,完成先根遍历二叉树功能    
    /*-------begin--------*/
    if (T == NULL)
        return;
    print(T->data);
    preOrder(T->lchild);
    preOrder(T->rchild);
    /*-------end--------*/
}

/*
函数名: inOrder
函数功能:中根遍历二叉树
参数:二叉树根结点指针
返回值:无
*/
void inOrder(BiTree* T)
{
    //请在此处填写代码,完成中根遍历二叉树功能    
/*-------begin--------*/
    if (T == NULL)
        return;
    
    inOrder(T->lchild);
    print(T->data);
    inOrder(T->rchild);

/*-------end--------*/
}

/*
函数名:postOrder
函数功能:后根遍历二叉树
参数:二叉树根结点指针
返回值:无
*/
void postOrder(BiTree* T)
{
    //请在此处填写代码,完成后根遍历二叉树功能    
/*-------begin--------*/
    if (T == NULL)
        return;
    
    postOrder(T->lchild);
    postOrder(T->rchild);
    print(T->data);

/*-------end--------*/
}



int main(void)
{
    BiTree* T;
    T = createBiTree(); //调用创建二叉树功能,得到二叉树的根结点指针


    preOrder(T);//调用先根遍历二叉树,按先根遍历顺序输出二叉树结点功能 
    cout << endl; //换行
    inOrder(T);//调用中根遍历二叉树,按中根遍历顺序输出二叉树结点功能 
    cout << endl;
    postOrder(T);//调用后根遍历二叉树,按后根遍历顺序输出二叉树结点功能 

    return 1;
}

第2关:完成二叉树相关应用

任务描述

假设我们用一棵二叉树存储你的家族族谱:
对于任意一个结点来说,左孩子代表长子或长女,右孩子代表兄弟或姐妹。
结点存储的是每个人的代号。
本关任务要求:输入某人的代号,输出此人的所有兄弟姐妹。

相关知识

森林、树与二叉树
下面图一所示的树表示一个家族族谱。
在这里插入图片描述

如果采用“任务描述”中的二叉树来表示该家族族谱,则对应的二叉树为图二所示。
在这里插入图片描述
因此,可以采用二叉树的存储结构来存储一棵树,并利用二叉树的相关操作来进行树的操作。

在图二所表示的树中,节点B、C、D互为兄弟,节点EF互为兄弟。

思考:森林如何转换为“任务描述”中的二叉树?

编程要求

根据提示,在右侧编辑器Begin-End处补充代码,完成本关任务。

测试说明

平台会对你编写的代码进行测试,先跟遍历输入序列:

ABC##D##E#F#G##;创建一棵家谱二叉树
测试输入:B
预期输出:D

测试输入:A;
预期输出: E F G

开始你的任务吧,祝你成功!

#include <iostream>
using namespace std;
 
#include <stdlib.h>
 
typedef char DataType;

//二叉树结点定义 
//此处进行二叉树结构定义
/*-------begin------*/

struct node
{
    DataType info; //存放结点数据 
    struct node* lchild, * rchild, * parent; //指向左右孩子的指针 
};
typedef struct node* BiTree;
/*-----end---------*/



void print(DataType d)
 {
   cout<<d<<" ";
 }

//初始化二叉树的结点序列
char treeData[] ="ABC##D##E#F#G##"; 

/*
函数名:createBiTree
函数功能:读取treeData 数组中的字符序列,按先序遍历思想进行二叉树创建二叉树,并返回二叉树的根结点指针 
参数:双亲节点parent, 以及先序遍历字符序列
返回值:二叉树的根结点指针 
*/ 
//在此处填入代码
/*----------begin-------------*/
int i = 0;
BiTree createBiTree(BiTree T, char treeData[])
{
    char ch = treeData[i];
    i++;
    BiTree  root;

    if (ch == '#') root = NULL;
    else {
        root = new struct node;
        root->info = ch;
        root->parent = T;
        root->lchild = createBiTree(root, treeData);
        root->rchild = createBiTree(root, treeData);
    }
    return root;
}


/*----------end-------------*/

/* 函数名:Sibling 
* 参数T:树的节点
* 功能:输出结点T的所有兄弟姐妹
* 返回值:无
*/void Sibling(BiTree root)
{
    //在此处填入代码
    /*----------begin-------------*/
    BiTree T = root;
    while (T->parent != NULL && T->parent->rchild == T)
    {
        print(T->parent->info);
        T = T->parent;
    }
    T = root;
    while (T->rchild != NULL)
    {
        print(T->rchild->info);
        T = T->rchild;
    }

    /*----------end-------------*/
}

/*
函数名:preOrder
函数功能:先根遍历二叉树 ,并找到值为ch的结点指针
参数:根结点指针 BiTree *T  ,需查找的结点值 ch 
返回值:无 
*/
 
//在此处填入代码,利用先序遍历,找到结点值ch后调用函数sibling输出该结点的所有兄弟姐妹,以空格分界
/*----------begin-------------*/
void preOrder(BiTree T, char ch)
{

    if (T == NULL)
        return;
 
    else if (T->info == ch)
        Sibling(T);
    preOrder(T->lchild, ch);
    preOrder(T->rchild, ch);
}


/*----------end-------------*/
 


 
int main(void)  
{  
    BiTree    T;  
    T= createBiTree(NULL,treeData); //创建树
	
 
	char ch ;
	fflush(stdin);
    cin>>ch; //输入某人的代号
    preOrder(T, ch); //调用函数输出ch的所有兄弟姐妹
   
    return 1;
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值