DS二叉树判断--同一棵二叉树?

题目描述

二叉树分别以数组存储方式创建、以先序遍历序列创建。输入二叉树的数组存储、先序遍历结果,判断根据它们创建的二叉树是否是同一棵二叉树。

输入

测试次数t

每组测试数据两行:

第一行:二叉树的数组存储(英文字母表示树结点,#表示空树)

第二行:二叉树的先序遍历结果(英文字母表示树结点,#表示空树)

输出

对每组测试数据,如果两种方式创建的是同一棵二叉树,输出YES,否则,输出NO。

输入样例1

3
ABCDE
ABD##E##C##
ABC##DE####W##F
AB##CDW###E#F##
abc##d
ab##c#d##

输出样例1

YES
YES
NO

NOTICE:我一开始的想法是根据先序遍历创建完二叉树后,层次遍历这棵二叉树,如果得到的遍历结果根输入中的数组存储结果相同的话,则说明是同一棵树,但是最后发现给的样例的第三组没过,自己在纸上写了一下,才发现这种算法有漏洞;

回到正题,这个题首先要搞懂数组存储的顺序是啥,其实就是从上往下,从左往右的顺序;这个题需要在先序创建二叉树时,将本来视为空的#字符,也创建一个结点将他放到二叉树中;之后对二叉树进行层次遍历,将遍历到的每个字符与数组存储结果字符串的每个字符逐个进行比较。

#include <iostream>
#include <string>
#include <queue>
using namespace std;

class BiTreeNode
{
public:
	char data;
	BiTreeNode* lchild;
	BiTreeNode* rchild;
	BiTreeNode():data(' '),lchild(nullptr),rchild(nullptr){}
	~BiTreeNode(){}
};

class BiTree
{
private:
	BiTreeNode* root;
	BiTreeNode* Create(string s, int& i)
	{
		BiTreeNode* t = nullptr;
		if (s[i] != '#')
		{
			t = new BiTreeNode;
			t->data = s[i];
			t->lchild = Create(s, ++i);
			t->rchild = Create(s, ++i);
		}
		else
		{
			t = new BiTreeNode;
			t->data = '#';
			t->lchild = nullptr;
			t->rchild = nullptr;
		}
		return t;
	}
public:
	void Create(string s)
	{
		int i = 0;
		root = Create(s, i);
	}
	void test(string s)
	{
		queue<BiTreeNode*> q;
		int index = 0;

		q.push(root);
		while (index != s.length())
		{
			if (q.front() != nullptr)//空指针直接跳过判断,且空指针无左右孩子,不需要入队列
			{
				if (q.front()->data != s[index])
				{
					cout << "NO" << endl;
					return;
				}
				
				q.push(q.front()->lchild);
				q.push(q.front()->rchild);
				
			}
			q.pop();
			index++;
		}
		cout << "YES" << endl;
	}
};

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		string s1, s2;
		BiTree mytree;

		cin >> s1 >> s2;
		mytree.Create(s2);
		mytree.test(s1);

	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值