L2-006 树的遍历 (层序遍历)
根据访问根节点与左右子树的先后顺序,二叉树一般有三种遍历方式:先序遍历、中序遍历和后序遍历。
只要给定中序遍历序列与先序或后序中的一种,可以还原二叉树结构。学习数据结构课程时,一直都只会手动构建还原二叉树。今天试着解决了该问题,记录一下成果。
#include<iostream> #include<cstdio> using namespace std; const int maxn = 50; int preorder[maxn], inorder[maxn]; struct Node{ int l, r; }nodes[maxn]; int build(int pl, int pr, int il, int ir) { // 以[pl,pr] [il, ir]建立二叉树,返回根节点 if(pl>pr) return 0; if(il>ir) return 0; int root = preorder[pl]; // 在中序遍历中找到跟节点,分成左右子树递归建树 int pos = il; while(inorder[pos]!=root) pos++; int _left = pos - il; nodes[root].l = build(pl+1, pl+_left, il, pos-1); nodes[root].r = build(pl+_left+1, pr, pos+1, ir); return root; } void PreReverse(int rt) { // 先序遍历 cout<<rt<<' '; if(nodes[rt].l) PreReverse(nodes[rt].l); if(nodes[rt].r) PreReverse(nodes[rt].r); } void PostReverse(int rt) { // 后序遍历 if(nodes[rt].l) PostReverse(nodes[rt].l); if(nodes[rt].r) PostReverse(nodes[rt].r); cout<<rt<<' '; } int main() { int N; cin>>N; for(int i=0;i<N;i++) cin>>preorder[i]; for(int i=0;i<N;i++) cin>>inorder[i]; int rt = build(0, N-1, 0, N-1); PreReverse(rt); PostReverse(rt); /* 7 3 5 7 6 1 8 2 7 5 1 6 3 8 2 后序遍历结果: 7 1 6 5 2 8 3 */ return 0; }
稍加修改应该可以解决此题(L2-006 树的遍历),最后输出层序遍历的序列,即BFS。(开始理解错了,对结果没影响)
AC代码如下:
#include<iostream> #include<cstdio> #include<queue> using namespace std; const int maxn = 50; int postorder[maxn], inorder[maxn]; struct Node{ int l, r; }nodes[maxn]; int build(int pl, int pr, int il, int ir) { // 以[pl,pr] [il, ir]建立二叉树,返回根节点 if(pl>pr) return 0; if(il>ir) return 0; int root = postorder[pr]; // 在中序遍历中找到跟节点,分成左右子树递归建树 int pos = il; while(inorder[pos]!=root) pos++; int _left = pos - il; nodes[root].l = build(pl, pl+_left-1, il, pos-1); nodes[root].r = build(pl+_left, pr-1, pos+1, ir); return root; } int main() { int N; cin>>N; for(int i=0;i<N;i++) cin>>postorder[i]; for(int i=0;i<N;i++) cin>>inorder[i]; int rt = build(0, N-1, 0, N-1); cout<<rt; queue<int> q; if(nodes[rt].l) q.push(nodes[rt].l); if(nodes[rt].r) q.push(nodes[rt].r); while(!q.empty()) { int k = q.front(); q.pop(); cout<<' '<<k; if(nodes[k].l) q.push(nodes[k].l); if(nodes[k].r) q.push(nodes[k].r); } return 0; }
// 2019.3.21 更新
今天做题发现层序遍历并不是单纯的BFS,在leetcode上碰到这样一个需要严格按照树的层次输出的题:
二叉树结构: 输出结果:
想了半天并没有想到标记每一个层次的办法,搜索解答才恍然大悟,代码非常简单!
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { queue<TreeNode*> q; q.push(root); vector<vector<int> > ans; if(root==NULL) return ans; while(!q.empty()) { vector<int> tmp; // 保存每一层的遍历结果 int size = q.size(); while(size--) { TreeNode *now = q.front(); q.pop(); tmp.push_back(now->val); if(now->left) q.push(now->left); if(now->right) q.push(now->right); } ans.push_back(tmp); } return ans; } };