多尝试画图模拟,将栈和队列进行可视化更清晰
#include<bits/stdc++.h>
using namespace std;
typedef struct TreeNode{
int val;
struct TreeNode * left;
struct TreeNode * right;
}TreeNode;
vector<int> preOrder(TreeNode* root) //先序遍历
{
vector<int> res;//存储输出结果 先序输出的结果
if (root == nullptr) return res;
stack<TreeNode *> s;//定义一个栈来实现先序遍历
s.push(root);//入栈
while (!s.empty())//如果不为空执行
{
root = s.top();//弹出栈顶元素
res.push_back(root->val);//并输出(这里是存入)
s.pop();//删除栈顶元素
if (root->right != nullptr)//然后先压右孩子,再压左孩子
s.push(root->right);
if (root->left != nullptr)
s.push(root->left);
}
return res;
}
//先序遍历,,就是用一个栈进行维护,从根节点开始输入,然后每次取出栈顶
//取出一个就输出一个,然后再把这个根的的俩个孩子压到栈里去,先压右再压左
vector<int> preOrder2(TreeNode* root) { //先序遍历
vector<int> res;
if(root == nullptr) return res;
stack<TreeNode *> s;
while(!s.empty() || root!=nullptr)
{
if(root != nullptr)//一直向左节点遍历并输出用栈接受
{
s.push(root);//入栈
res.push_back(root->val);//输出
root = root->left;//往下走
}
else //如果左节点为空,则返回当前节点的根节点的右节点
{
root = s.top()->right;//s.top是根节点,用栈模拟即可知道
s.pop();//说明一个根节点的左右孩子都遍历完了所以删除
}
}
return res;
}
/*中序遍历*/
vector<int> inOrder(TreeNode *root)
{
vector<int> res;
if(root == nullptr) return res;
stack<TreeNode *> s;
while(!s.empty() || root!=nullptr)
{
if(root != nullptr)//一路遍历到空一直向左遍历 但是不输出
{
s.push(root);//入栈
root = root->left;//向左下
}
else //如果到了最左边的空
{
root = s.top();//返回到该节点的根节点
res.push_back(root->val);//并且输出
s.pop();//然后把根节点删了
root = root->right;//再跳到该节点的右节点 多体会一下栈就行了
}
}
return res;
}
/*后序遍历*/
//通过实现根右左 然后用栈进行反置来变成左右根
vector<int> preOrder3(TreeNode* root)
{
vector<int> res;
if (root == nullptr) return res;
stack<TreeNode *> s;//根右左
stack<TreeNode *> s2;//左右根
s.push(root);//入栈
while (!s.empty())//根先序遍历的根左右差不多,只是这边是先压左孩子后压右孩子
{ //但是先序遍历是先压右孩子再压左孩子
root = s.top();
s2.push(root);//入栈
s.pop();
if (root->left != nullptr)
s.push(root->left);
if (root->right != nullptr)
s.push(root->right);
}
while(!s2.empty())
{
res.push_back(s2.top()->val);//输出
s2.pop();
}
return res;
}
/*层次遍历*///队列进行维护先进先出
vector<int> printFromTopToBottom(TreeNode* root) {
vector<int> res;
if(root == nullptr) return res;
queue<TreeNode *> q;
q.push(root);
while(!q.empty())//先进左再进右右
{
root = q.front();//取出队头
q.pop();
res.push_back(root->val);//输出
if(root->left != nullptr)//左孩子入队
q.push(root->left);
if(root->right != nullptr)//右孩子入队
q.push(root->right);
}
return res;
}
//本人只是借鉴代码,注释是自己加的,原作者更加详细
/*
作者:幼稚园小朋友
链接:https://www.acwing.com/blog/content/522/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/