题目描述
假设二叉树用二叉链表存储,用先序序列结果创建。输入二叉树的先序序列,请你先创建二叉树,并对树做个镜面反转,再输出反转后的二叉树的先序遍历、中序遍历、后序遍历和层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。
--程序要求--
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
输入
测试次数t
每组测试数据是一个二叉树的先序遍历序列,#表示空树
输出
对每棵二叉树,输出镜面反转后的先序、中序、后序和层次遍历序列。如果空树,输出四个NULL(后面不加空格)。如下:
NULL
NULL
NULL
NULL
输入样例1
3
41#32###65##7##
AB#C##D##
AB##C##
输出样例1
4 6 7 5 1 3 2
7 6 5 4 3 2 1
7 5 6 2 3 1 4
4 6 1 7 5 3 2
A D B C
D A C B
D C B A
A D B C
A C B
C A B
C B A
A C B
以下是思路
镜面反转二叉树很简单,右树变左树,左树变右树即可。
这题要求只能用iostream头文件,这意味着层次遍历的时候不能用C++自带的队列来做。前中后序遍历倒是比较简单,用递归实现即可。
那么最大的问题就是层序遍历在不使用队列的情况下该如何实现。这里先来分析层序遍历的特点
1.从根节点开始,先访问左子树(类似前序遍历)
2.逐层向下遍历(说明各个节点应当有自己的level域来存放该节点所在层的编号。
那么问题就变成了给每个节点的level赋对应的值。并利用前序遍历的结果打印输出。那么对应的Node和Tree的成员应该有以下这些。
#include <iostream>
using namespace std;
class Node
{
public:
Node* left, * right;
char data;
int level;//节点所在层级
Node() { left = right = NULL;level = 0;data = '-'; }
};
class Tree
{
public:
Node* root;
Node** list;//存放前序遍历的结果
string str;
int pos;
int lev = 0;//当前二叉树层级
int size;
Tree(string s)
{
str = s; pos = 0;size = 0;
root = create(lev);
list = new Node * [size + 1];
pos = 0;
}
Node* create(int lev);
void pre(Node*end);
void mid(Node* end);
void last(Node* end);
void levelp();
};
给节点找level值可以选择在建树的时候就赋值,也可以选择在前序遍历的时候赋值,这里选择在建树的时候就找到对应的level值。(那么就需要在递归的时候往里头传入一个参数,这个参数就是节点所在层次)。同时只需要换一下建左右树的顺序就能得到对应的镜像二叉树。
Node* Tree::create(int lev)
{
char temp = str[pos];
pos++;
if (temp == '#')
{
return NULL;
}
else
{
size++;
Node* tmp = new Node();
tmp->data = temp;
tmp->level = lev;
lev++;
tmp->right = create(lev);
tmp->left = create(lev);
return tmp;
}
}
前中后序遍历在C++中先序构建二叉树+输出(递归实现)这篇讲过了,这里就不多说了。主要是层次遍历。这里用list存放先序遍历的结果(Node*类型)。再去遍历这个数组即可得到结果。
void Tree::levelp()
{
int i = 0;//size
int tmp = 0;//level
while (i < size)
{
for (int j = 0;j < size;j++)
{
if (tmp == list[j]->level)
{
cout << list[j]->data << " ";
i++;
}
}
tmp++;
}
}
以下是代码
#include <iostream>
using namespace std;
class Node
{
public:
Node* left, * right;
char data;
int level;
Node() { left = right = NULL;level = 0;data = '-'; }
};
class Tree
{
public:
Node* root;
Node** list;
string str;
int pos;
int lev;
int size;
Tree(string s)
{
str = s; pos = 0;size = 0;lev = 0;
root = create(lev);
list = new Node * [size + 1];
pos = 0;
}
Node* create(int lev);
void pre(Node*end);
void mid(Node* end);
void last(Node* end);
void levelp();
};
Node* Tree::create(int lev)
{
char temp = str[pos];
pos++;
if (temp == '#')
{
return NULL;
}
else
{
size++;
Node* tmp = new Node();
tmp->data = temp;
tmp->level = lev;
lev++;
tmp->right = create(lev);
tmp->left = create(lev);
return tmp;
}
}
void Tree::pre(Node* end)
{
if (end)
{
cout << end->data << " ";
list[pos] = end;
pos++;
pre(end->left);
pre(end->right);
}
}
void Tree::mid(Node* end)
{
if (end)
{
mid(end->left);
cout << end->data << " ";
mid(end->right);
}
}
void Tree::last(Node* end)
{
if (end)
{
last(end->left);
last(end->right);
cout << end->data << " ";
}
}
void Tree::levelp()
{
int i = 0;//size
int tmp = 0;//level
while (i < size)
{
for (int j = 0;j < size;j++)
{
if (tmp == list[j]->level)
{
cout << list[j]->data << " ";
i++;
}
}
tmp++;
}
}
int main()
{
int t;
cin >> t;
while (t--)
{
string str;
cin >> str;
Tree tree(str);
if (tree.root)
{
tree.pre(tree.root);
cout << endl;
tree.mid(tree.root);
cout << endl;
tree.last(tree.root);
cout << endl;
tree.levelp();
cout << endl;
}
else
{
for (int i = 0;i <= 3;i++)
{
cout << "NULL" << endl;
}
}
}
}