题目描述
给出一棵二叉树的特定字符先序遍历结果(空子树用字符'#'表示),构建该二叉树,并输出该二叉树的双亲表示法结果
双亲表示法的数组下标从0开始,根结点必定是在下标0元素,且根结点的双亲下标为-1,左右孩子按下标递增顺序排列,
结点下标是层次遍历顺序。
输入
第一个输入t,表示有t棵二叉树
接着t行,每行输入含特定字符的二叉树先序遍历序列
输出
共输出2t行
每棵二叉树输出两行,第一行输出各个结点的数值,第二行输出各结点的双亲下标
输入样例1
3
AB#C##D##
ABD##E##C##
AB##CDW###E#F##
输出样例1
A B D C
-1 0 0 1
A B C D E
-1 0 0 1 1
A B C D E W F
-1 0 0 2 2 3 4
NOTICE:这个题只要在原来二叉树的算法基础上加个双亲指针parent就可以,然后借助层次遍历来创建双亲表示法下的树的存储结构;(有一个地方没搞懂,就是参数为什么要引用?我单步调试了一下,发现不用引用的话根结点是空的,也就是根本就没有创建?)
#include <iostream>
#include <queue>
using namespace std;
class BiTreeNode
{
private:
char data;
BiTreeNode* lchild;
BiTreeNode* rchild;
BiTreeNode* parent;
public:
BiTreeNode():data(' '),lchild(nullptr),rchild(nullptr),parent(nullptr) {}
friend class BiTree;
};
class BiTree
{
private:
BiTreeNode* root;
//根据题目要求定义的新的属性
BiTreeNode* a[1000];//这里非常关键,数组存储的是指针而非数据,方便find函数
int b[1000];//双亲下标
int len;//两个数组的长度
void Create(BiTreeNode* &t,BiTreeNode* par)//指针传引用???
{
char ch;
cin >> ch;
if (ch != '#')
{
t = new BiTreeNode;
t->data = ch;
t->parent = par;
Create(t->lchild, t);
Create(t->rchild, t);
}
else
t = nullptr;
}
int find(BiTreeNode* t)//根据传过来的双亲指针,找到对应的双亲下标
{
if (t == nullptr)
return -1;
for (int i = 0; i < 1000; i++)
{
if (t == a[i])
return i;
}
}
public:
void Create()
{
Create(root, nullptr);
}
void BFS()
{
queue<BiTreeNode*> q;
int index = 0;//数组a的下标
if (root != nullptr)
{
q.push(root);
while (!q.empty())
{
a[index] = q.front();
b[index] = find(q.front()->parent);
index++;
if (q.front()->lchild != nullptr)
q.push(q.front()->lchild);
if (q.front()->rchild != nullptr)
q.push(q.front()->rchild);
q.pop();
}
}
len = index;
}
void display()
{
for (int i = 0; i < len; i++)
{
cout << a[i]->data;
if (i == len - 1)
cout << endl;
else
cout << " ";
}
for (int i = 0; i < len; i++)
{
cout << b[i];
if (i == len - 1)
cout << endl;
else
cout << " ";
}
}
};
int main()
{
int t;
cin >> t;
while (t--)
{
BiTree mytree;
mytree.Create();
mytree.BFS();
mytree.display();
}
return 0;
}