目录
二叉树的遍历方法包括两种:深度优先遍历与广度优先遍历
下面分别介绍这两种遍历方法的具体实现。
深度优先遍历:
即先往深走,遇到叶子节点再往回走。又包括前序、中序、后序遍历,可分别由递归法与迭代法实现。(PS:这里的三种顺序指的是中间节点的遍历顺序)
前序遍历:中左右
中序遍历:左中右
后序遍历:左右中
二叉树节点定义:
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
递归法:
前序
// 递归法
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec){
if(cur == nullptr) return;
vec.push_back(cur->val);
traversal(cur->left, vec);
traversal(cur->right, vec);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> preVec;
if(root==nullptr) return preVec;
traversal(root, preVec);
return preVec;
}
};
中序
// 递归法
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec){
if(cur == nullptr) return;
traversal(cur->left, vec);
vec.push_back(cur->val);
traversal(cur->right, vec);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> mid_vec;
if(root == nullptr) return mid_vec;
traversal(root, mid_vec);
return mid_vec;
}
};
后序
// 递归法
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec){
if(cur == nullptr) return;
traversal(cur->left, vec);
traversal(cur->right, vec);
vec.push_back(cur->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> post_vec;
if(root == nullptr) return post_vec;
traversal(root, post_vec);
return post_vec;
}
};
迭代法:
前序
// 迭代法
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> preVec;
stack<TreeNode*> preStack;
if(root==nullptr) return preVec;
preStack.push(root);
while(!preStack.empty()){
TreeNode* cur = preStack.top();
preStack.pop();
preVec.push_back(cur->val); // 前序
// 中节点的右左入栈,左右出栈
if(cur->right) preStack.push(cur->right);
if(cur->left) preStack.push(cur->left);
}
return preVec;
}
};
中序
// 迭代法
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> mid_vec;
stack<TreeNode*> mid_stack;
if(root == nullptr) return mid_vec;
TreeNode* cur = root;
while(cur || !mid_stack.empty()){
if(cur){
mid_stack.push(cur);
cur = cur->left;
}
else{
cur = mid_stack.top();
mid_stack.pop();
mid_vec.push_back(cur->val); // 中序
cur = cur->right;
}
}
return mid_vec;
}
};
后序
// 迭代法
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> post_vec;
stack<TreeNode*> post_stack;
if(root == nullptr) return post_vec;
post_stack.push(root);
while(!post_stack.empty()){
TreeNode* cur = post_stack.top();
post_stack.pop();
post_vec.push_back(cur->val); //前序(后面逆转)
//左右入栈,右左出栈
if(cur->left) post_stack.push(cur->left);
if(cur->right) post_stack.push(cur->right);
}
// 中右左->左右中
reverse(post_vec.begin(),post_vec.end());
return post_vec;
}
};
迭代法(统一写法)
前序
// 迭代法(统一风格)
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> preVec;
stack<TreeNode*> preStack;
if(root) preStack.push(root);
while(!preStack.empty()){
TreeNode* cur = preStack.top();
if(cur){ // 入栈标记处理节点
preStack.pop();
if(cur->right) preStack.push(cur->right); //右入栈
if(cur->left) preStack.push(cur->left); //左入栈
preStack.push(cur); //中入栈
preStack.push(nullptr); //push空节点,标记处理节点
}
else{ // 遇空节点出栈处理
preStack.pop();
preVec.push_back(preStack.top()->val);
preStack.pop();
}
}
return preVec;
}
};
中序
// 迭代法
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> mid_vec;
stack<TreeNode*> mid_stack;
if(root) mid_stack.push(root);
while(!mid_stack.empty()){
TreeNode* cur = mid_stack.top();
if(cur){ // 入栈标记处理节点
mid_stack.pop();
if(cur->right) mid_stack.push(cur->right);
mid_stack.push(cur);
mid_stack.push(nullptr);
if(cur->left) mid_stack.push(cur->left);
}
else{ // 遇空节点出栈处理
mid_stack.pop();
mid_vec.push_back(mid_stack.top()->val); // 中序
mid_stack.pop();
}
}
return mid_vec;
}
};
后序
// 迭代法(统一风格)
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> post_vec;
stack<TreeNode*> post_stack;
if(root) post_stack.push(root);
while(!post_stack.empty()){
TreeNode* cur = post_stack.top();
if(cur){ // 入栈标记处理节点
post_stack.push(nullptr); // 中
if(cur->right) post_stack.push(cur->right); // 右
if(cur->left) post_stack.push(cur->left); // 左
}
else{ // 遇空节点出栈处理
post_stack.pop();
post_vec.push_back(post_stack.top()->val);
post_stack.pop();
}
}
return post_vec;
}
};
广度优先遍历:
一层一层的去遍历。
迭代法:
// 迭代法
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode*> que;
if(root) que.push(root);
while(!que.empty()){
// 记录每层元素
int size = que.size();
vector<int> level_vec;
for(int i=0; i<size; i++){
TreeNode* cur = que.front();
que.pop();
level_vec.push_back(cur->val);
// 下一层节点入队(left->right进,left->right出)
if(cur->left) que.push(cur->left);
if(cur->right) que.push(cur->right);
}
res.push_back(level_vec);
}
return res;
}
};
递归法:
详见注释.
// 递归法:先向下遍历左子树至最深层,再按照节点向上返回,遍历右子树
//(故需要定义深度depth,表示节点所处层数)
class Solution {
public:
void order(TreeNode* cur, vector<vector<int>>& res, int depth){
// 终止条件(返回上一层递归 向上返回
if(!cur) return;
// 若首次遍历至当前depth,新建vector 记录当前层节点
if(res.size() == depth) res.push_back(vector<int>());
res[depth].push_back(cur->val);
// 向下遍历 左子树
if(cur->left) order(cur->left, res, depth+1);
// 再向下遍历 右子树
if(cur->right) order(cur->right, res, depth+1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
int depth = 0;
order(root, res, depth);
return res;
}
};
二叉树的构建
根据二叉树的前序、中序遍历构建二叉树,返回二叉树的后序遍历
#include<iostream>
#include<vector>
#include<string>
using namespace std;
void output(vector<string>& input){
for(auto it=input.begin(); it!=input.end(); it++){
cout<<*it<<endl;
}
}
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
class solution
{
private:
TreeNode* traversal(string pre_order, string mid_order){
//
if(pre_order.size() == 0){
return nullptr;
}
// get mid_node
int mid_index;
for(int i=0; i<mid_order.size(); i++){
if(mid_order[i] == pre_order[0]){
mid_index = i;
break;
}
}
TreeNode* mid = new TreeNode(mid_order[mid_index]);
// mid_order
string left_mid(mid_order.begin(), mid_order.begin()+mid_index);
string right_mid(mid_order.begin()+mid_index+1, mid_order.end());
// pre_order
string left_pre(pre_order.begin()+1, pre_order.begin()+1+left_mid.size());
string right_pre(pre_order.begin()+1+left_mid.size(), pre_order.end());
//
mid->left = traversal(left_pre, left_mid);
mid->right = traversal(right_pre, right_mid);
return mid;
}
public:
TreeNode* getTree(string& pre_order, string& mid_order){
TreeNode* root;
root = traversal(pre_order, mid_order);
return root;
}
void postTraversal(TreeNode* root, string& post_order){
if(!root) return;
postTraversal(root->left, post_order);
postTraversal(root->right, post_order);
post_order.push_back(root->val);
}
};
int main()
{
// input
vector<string> pre_order;
vector<string> mid_order;
while(cin){
string input;
cin>>input;
pre_order.push_back(input);
cin>>input;
mid_order.push_back(input);
}
// // debug input
// output(pre_order);
// output(mid_order);
// solve
solution my_solve;
vector<string> post_order(pre_order.size(), "");
for(int i=0; i<pre_order.size(); i++){
TreeNode* root = my_solve.getTree(pre_order[i], mid_order[i]);
my_solve.postTraversal(root, post_order[i]);
}
output(post_order);
return 0;
}