解析:这题主要考察二叉树的遍历,但是我们学习二叉树的时候我们都是使用二叉链表完成操作,这题如果还是用二叉链表,会很麻烦,因为给定的边两个结点你是不知道有没有之前创建了结点!所有我们要换一个思路,既然给定的点编号刚好是1~n那么我们直接用邻接矩阵存边的关系,第一个下标是弧尾,每一个结点后面挂一个孩子也就是弧头。我们也要边插入边统计入度,便于找到根节点,根节点的入度为0!
这里第一个代码是先存好边,然后再遍历的时候调整左右孩子的位置。注意到先序:根左右和后序:左右根,都是“左右”所以直接排序满足条件即可,根的遍历要么在孩子之前要么在孩子之后。但是中序遍历需要特殊处理,因为有只有一个孩子的情况且与父亲结点要满足关系,所以单独处理一个结点情况,两个结点还是满足“左根右”直接递归 输出 递归即可。
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve() {
int n;
cin >> n;
vector<vector<int>>g(n + 1); //邻接表存图
vector<int>in(n + 1); //统计每个结点的入度,找出根节点
int a, b;
for (int i = 1; i <= n - 1; i++) {
cin >> a >> b;
g[a].push_back(b);
in[b]++;
}
int root = -1;
for (int i = 1; i <= n; i++) {
if (in[i] == 0) { //找到入度为0的结点,即为根结点
root = i;
}
sort(g[i].begin(), g[i].end());
}
auto preOrder = [&](auto&& self, int root)->void{
//先序遍历序列 根 左 右
cout << root << " ";
for (auto p : g[root]) {
self(self, p);
}
};
preOrder(preOrder, root);
cout << endl;
auto inOrder = [&](auto&& self, int root)->void{
//中序遍历序列 左 根 右
if(g[root].size()==0){//叶子结点直接返回
cout<<root<<" ";
return;
}else if(g[root].size()==1){//只有一个孩子
if(g[root][0]>root){//做左孩子
self(self,g[root][0]);
cout<<root<<" ";
}else{//做右孩子
cout<<root<<" ";
self(self,g[root][0]);
}
}else{//有两个孩子
self(self,g[root][0]);
cout<<root<<" ";
self(self,g[root][1]);
}
};
inOrder(inOrder, root);
cout << endl;
auto reOrder = [&](auto&& self, int root)->void{
//后序遍历序列 左 右 根
for (auto p : g[root]) {
self(self, p);
}
cout << root << " ";
};
reOrder(reOrder, root);
cout << endl;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
solve();
return 0;
}
第二套代码是先处理好边的关系,再遍历。符号我们学二叉树遍历的逻辑。但是存储孩子用了哈希表暂存一下,再具体把左右孩子分别用数组存储(按照题设要求哟~),代表该下标的左右孩子。也要在存边的时候找到根节点!!!遍历时直接套数据结构的模板即可。特别注意一定要返回哟~这里数组元素为0代表是空结点哦!!!会爆栈的!
#include<bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define int long long
void solve() {
int n;
cin >> n;
unordered_map<int, vector<int>>mp; //直接先存下所有孩子
//存树结构判断满足条件左右孩子
vector<int>l(n + 1);
vector<int>r(n + 1);
vector<bool>hasFa(n+1);
int a, b;
for (int i = 1; i <= n - 1; i++) {
cin >> a >> b;
mp[a].push_back(b);
hasFa[b]=true;
}
int root = -1;
for (int i = 1; i <= n; i++) {
if (hasFa[i]==false) {
root = i;
}
if (mp[i].size() == 1) {
if (mp[i][0] > i) {
l[i] = mp[i][0];
} else r[i] = mp[i][0];
} else if(mp[i].size()==2){
l[i] = min(mp[i][0], mp[i][1]);
r[i] = max(mp[i][0], mp[i][1]);
}
}
auto PreOrder = [&](auto&& self, int root)->void{
//根 左 右
cout << root << " ";
if(l[root]!=0)self(self, l[root]);
if(r[root]!=0)self(self, r[root]);
};
PreOrder(PreOrder, root);
cout << endl;
auto InOrder = [&](auto&& self, int root)->void{
//左 根 右
if(l[root]!=0)self(self, l[root]);
cout << root << " ";
if(r[root]!=0)self(self, r[root]);
};
InOrder(InOrder, root);
cout << endl;
auto ReOrder = [&](auto&& self, int root)->void{
//左 右 根
if(l[root]!=0)self(self, l[root]);
if(r[root]!=0)self(self, r[root]);
cout << root << " ";
};
ReOrder(ReOrder, root);
cout << endl;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
solve();
return 0;
}

京公网安备 11010502036488号