您的位置:首页 > 游戏 > 手游 > 【树的遍历】

【树的遍历】

2024/10/6 18:30:04 来源:https://blog.csdn.net/m0_73669127/article/details/141071851  浏览:    关键词:【树的遍历】

题目

代码

#include<bits/stdc++.h>
using namespace std;const int N = 40;int in[N], pos[N]; //中序、后序
int idx[N]; //中序的值->索引
unordered_map<int, int> l, r; //根节点的左、右树根节点
int n;
int build(int il, int ir, int pl, int pr)
{int root = pos[pr];int k = idx[root];if(il < k) l[root] = build(il, k-1, pl, pl + k - 1 - il);if(k < ir) r[root] = build(k+1, ir, pl + k - 1 - il + 1, pr-1);return root;
} 
void bfs(int root)
{queue<int> q;q.push(root);while(!q.empty()){int fr = q.front();cout << fr << " ";q.pop();if(l.count(fr)) q.push(l[fr]);if(r.count(fr)) q.push(r[fr]);}
}
int main()
{cin >> n;for(int i = 1; i <= n; i++) cin >> pos[i];for(int i = 1; i <= n; i++) cin >> in[i], idx[in[i]] = i;int root = build(1, n, 1, n);bfs(root);return 0;
}

思考

对于树的遍历,算法应设计如下

层序:bfs(queue)

先序:dfs(递归)  (先输出)    or dfs(stack)(不论先后输出)

中序:dfs(递归)(中间输出)

后序:dfs(递归)(后面输出)

理解

queue+先左再右就可以保证同一层中从左到右,不同层之间从上到下。

根据序列遍历的要求,要先左根再右根。所以递归要先左再右。

但是用stack模拟要反着来,先压入右节点,再压入左节点。然后左节点出又是如此,这样就像上面那个先左再右,右生左继续先左再右了。

提一个问题:为什么递归中改变输出的时机可以在不同序列间切换,但是在stack中不行?

答:递归中的子递归也有输出操作,从代码上看,就像左子输出、右子输出和根节点输出在排序一样;而stack中的输出就是当前top节点的值(不是递归,没有子输出),于是输出顺序和访问顺序相同,是定死的先序。要改变序列,必须从访问顺序上下手

补充

(递归,先中后序列)

void firsto(int root)
{cout << root << " ";if(l.count(root)) firsto(l[root]);if(r.count(root)) firsto(r[root]);
}
void ino(int root)
{if(l.count(root)) ino(l[root]);cout << root << " ";if(r.count(root)) ino(r[root]);
}
void poso(int root)
{if(l.count(root)) poso(l[root]);if(r.count(root)) poso(r[root]);cout << root << " ";
}

(stack,先序)

void first_dfs(int root)
{stack<int> s;s.push(root);while(!s.empty()){int fr = s.top();cout << fr << " ";s.pop();if(r.count(fr)) s.push(r[fr]);if(l.count(fr)) s.push(l[fr]);}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com