头歌数据结构与算法——实验二:树

789 阅读5分钟

前置内容

typedef struct BiTNode
{
  char data;    //数据域
  struct BiTNode *lchild,*rchild;  //结构体指针 分别代表左孩子节点和右孩子节点
}BiTNode,*BiTree;

typedef struct BiTNode BiTNode 为 struct BiTNode 起别名

typedef struct BiTNode* BiTree 为 struct BiTNode* 起别名

第一关 先序创建二叉树

任务描述
本关任务:设计一个算法,根据二叉树的先序遍历序列创建二叉树,平台会输入创建好的二叉树的中序遍历序列

编程要求
输入
二叉树的先序遍历序列,其中,叶子结点的左右空子树用#表示

输出
该二叉树的中序遍历序列

测试说明
平台会对你编写的代码进行测试:

测试输入:
ABD##E##CF##G##

预期输出:
DBEAFCG
#include<iostream>
using namespace std;

typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;


void CreateBiTree(BiTree &T)
{
	//根据键盘输入,创建二叉树,在此处填入代码
	//先序创建二叉树
    char c;  //定义字符型变量,用于接收传入值
    c = getchar(); //获取用户输入

    if(c == '#'){
        T = NULL;  //若为#,代表空节点
    }else{
        T = new BiTNode; //创建一个新节点
        T->data = c; //将输入的字符赋值给节点数据
        CreateBiTree(T->lchild); //递归创建左子树
        CreateBiTree(T->rchild); //递归创建右子树
    }

    

}

第二关 两棵树是否相同

任务描述
本关任务:设计一个算法,判断两棵二叉树是否相同

编程要求
输入
两棵二叉树的先序遍历序列,其中,叶子结点的左右空子树用#表示

输出
是否相同

测试说明
平台会对你编写的代码进行测试:

测试输入:
ABD##E##CF##G##
ABD##E##CF##G##

预期输出:
两棵树相同

测试输入:
ABD##E##CF##G##
ABD##M##CF##G##

预期输出:
两棵树不相同
#include<iostream>
using namespace std;

typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;


int CmpTree(BiTree T1,BiTree T2)
{
	//判断两棵树是否完全相等
	//在此处写入代码,相等返回1,不相等返回0
    //若两树都为空,相等
    if(T1 == NULL && T2 == NULL){
        return 1;
    }else if(T1 == NULL || T2 == NULL){  //一树为空,一树不为空,两树不等
        return 0;
    }
    if(T1->data != T2->data){
        return 0;              //同一节点数据域不等,两树不等
    }
    return CmpTree(T1->lchild,T2->lchild) && CmpTree(T1->rchild,T2->rchild); //比较左右孩子节点
}

视频链接:【数据结构】判断两棵树是否相等_哔哩哔哩_bilibili

第三关 合并两棵二叉树

任务描述
本关任务:设计一个算法,将两棵二叉树进行合并,合并规则是:两棵树对应位置都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。例如:


编程要求
输入
两棵二叉树的先序遍历序列,其中,叶子结点的左右空子树用#表示

输出
合并后新树的先序遍历序列

测试说明
平台会对你编写的代码进行测试:

测试输入:
135###2##
21#4##3#7##

预期输出:
345457

image.png

#include<iostream>
using namespace std;

typedef struct BiTNode
{
	int data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;


BiTree MergeTree(BiTree T1,BiTree T2)
{
	//返回合并后的树的根节点
	//如果对应位置只有一棵树的结点存在,使用该结点作为合并后树的新结点
	//如果对应位置两棵树的结点均存在,创建一个新结点用于合并后树的结点,值为两个结点的值之和
	//在此处写入代码
    //如果T1为空,返回T2
    if(T1 == NULL){
        return T2;
    }
    //如果T2为空,返回T1
    if(T2 == NULL){
        return T1;
    }

    //为了节省空间,把T1当作返回对象
    //数据域相加
    T1->data += T2->data;
    //递归操作对应左右子树
    T1->lchild = MergeTree(T1->lchild,T2->lchild);
    T1->rchild = MergeTree(T1->rchild,T2->rchild);

    return T1;

	

}

视频链接:一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树_哔哩哔哩_bilibili

第四关 交换二叉树左右孩子

任务描述
本关任务:设计一个算法,将二叉树每个结点的左右孩子都交换位置

编程要求
输入
二叉树的先序遍历序列,其中空结点用#表示

输出
交换左右孩子后的二叉树先序遍历序列

测试说明
平台会对你编写的代码进行测试:

测试输入:
ABD##E##CF##G##

预期输出:
ACGFBED
#include<iostream>
using namespace std;

typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;


void SwapBiTree(BiTree &T)
{
	//交换二叉树每个结点的左孩子和右孩子
	//在此处填入代码
    //若空树,直接返回
    if(T == NULL){
        return;
    }

    //交换左右子树
    BiTree temp = T->lchild;
    T->lchild = T->rchild;
    T->rchild = temp;

    //对左右子树通过递归进行相同操作 
    SwapBiTree(T->lchild);
    SwapBiTree(T->rchild);
	
}

第五关 完全二叉树判断

任务描述
本关任务:设计一个算法,判断二叉树是否是完全二叉树

编程要求
输入
二叉树的先序遍历序列,其中空结点用#表示

输出
是否是完全二叉树,若是输出yes,否输出no

测试说明
平台会对你编写的代码进行测试:

测试输入:
ABD##E##CF##G##

预期输出:
yes
#include<iostream>
#include<queue>
using namespace std;

typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;


int isCompleteTree(BiTree T)
{
	//判断是否为完全二叉树,若是返回1,不是返回0
	//可使用c++的queue模板库
	//在此处填入代码
	 if (!T) return 1;  // 空树是完全二叉树

    queue<BiTree> q;
    q.push(T);

    bool foundNull = false; // 标记是否已经遇到空节点

    while (!q.empty()) {
        BiTree node = q.front();
        q.pop();

        if (node == nullptr) {
            foundNull = true; // 发现空节点
        } else {
            if (foundNull) {
                return 0; // 如果已经遇到空节点,但当前节点不是空节点,说明不是完全二叉树
            }
            // 继续遍历左右子树
            q.push(node->lchild);
            q.push(node->rchild);
        }
    }
    
    return 1;  // 遍历结束没有问题,说明是完全二叉树

}