数据结构二叉树遍历(前中后,递归非递归)
Posted zhao111222333444
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构二叉树遍历(前中后,递归非递归)相关的知识,希望对你有一定的参考价值。
这里写目录标题
前序
递归
class Solution
public:
vector<int> v;
vector<int> preorderTraversal(TreeNode* root)
//vector不能写在函数里,否则只会输出最后一个节点
if(root==nullptr)return v;
v.push_back(root->val);
if(root->left)
preorderTraversal(root->left);//注意没有return
if(root->right)
preorderTraversal(root->right);
return v;
;
非递归
先入根节点(为了一开始不为空进入循环)
栈顶出栈,并记录内容,
当前结点的右结点入栈
当前结点的左结点入栈
当栈不为空时重复上述过程。
class Solution
public:
vector<int> preorderTraversal(TreeNode* root)
vector<int> v;
if(root==nullptr)return v;
stack<TreeNode*> s;
s.push(root);
while(!s.empty())
TreeNode* node=s.top();
v.push_back(node->val);
s.pop();
if(node->right)//注意前序是根,左,右
//所以保证左在右的前面,右先入栈
s.push(node->right);
if(node->left)
s.push(node->left);
return v;
;
中序遍历
递归
class Solution
public:
vector<int> v;
vector<int> inorderTraversal(TreeNode* root)
if(root==nullptr)return v;
if(root->left)
inorderTraversal(root->left);
v.push_back(root->val);
if(root->right)
inorderTraversal(root->right);
return v;
;
非递归
根节点开始循环入栈左节点到没有为止,此时出栈顶(最左节点),并记录左节点,如果有右节点,就标记一个右节点为根节点。
等到下一次循环把这个节点作为根节点走1的遍历。如果没有这个节点就从栈顶取作为根节点再次循环1.
特殊:栈为空并且跟为空才可以结束循环
思路:
还是用栈辅助来做
1.root每次都去找当前所在位置的最左节点,然后出栈记录
2.按照左中右的规律,此时不能出中(此时的栈顶),要看它是否有左节点,走1的循环,每次找到最左节点时,root都指向了nullptr。
3.这里可以看到结束条件有两个:栈为空,root(node)为空。这是因为中序遍历优中后右的特性,会有一个时刻栈为空但右结点并未被遍历(最开始的根都出去了,在出去之前node指向了最初根的右节点,不是空),因此只有在curr也为空证明右结点不存在的情况下,才能结束遍历。
class Solution
public:
vector<int> inorderTraversal(TreeNode* root)
vector<int> v;
if(root==nullptr)return v;
stack<TreeNode*> s;
TreeNode* node=root;
while(node!=nullptr||!s.empty())
//while(node->left)每次循环在找到最左节点时node一定是空
while(node)
s.push(node);
node=node->left;
TreeNode* top=s.top();
v.push_back(top->val);
s.pop();
if(top->right)
node=top->right;
return v;
;
后序遍历
递归
class Solution
public:
vector<int> v;//递归每次都会走函数的全体,所以写外面
vector<int> postorderTraversal(TreeNode* root)
if(root==nullptr)return v;
if(root->left)
postorderTraversal(root->left);
if(root->right)
postorderTraversal(root->right);
v.push_back(root->val);
return v;
;
非递归
1.首先根节点开始一直入栈左节点到空,此时不能出因为可能要有右节点(右在根前),此时判断是否有节点为空或者是否访问过这个右节点了,就读节点,出栈,记录前一个节点
如果有右节点并且没有访问,此时root就是栈顶的右节点。
1.先访问最左节点
2.先看看最左节点有没有右节点,有的话就去访问,把右节点当root再次访问它的最左,如果没有的话这个就可以删除了。
法1:
class Solution
public:
vector<int> postorderTraversal(TreeNode* root)
vector<int> v;
if(root==nullptr)return v;
stack<TreeNode*> s;
TreeNode* prev;
while(root||!s.empty())
while(root)
s.push(root);
root=root->left;
TreeNode* mtop=s.top();
//先找到最左子树
//此时还不能删,可能有右子树
//没有的话就删
if(mtop->right==nullptr||mtop->right==prev)
v.push_back(mtop->val);
s.pop();
prev=mtop;//这是当前访问节点
//有的话先访问右子树
else
//访问右子树
if(mtop->right)
root=mtop->right;
return v;
;
法2利用前序辅助:
class Solution
public:
vector<int> postorderTraversal(TreeNode* root)
stack<TreeNode*> t;
vector<int> v;
if(root==nullptr)return v;
stack<TreeNode*> s;
s.push(root);
while(!s.empty())
TreeNode* node=s.top();
//v.push_back(node->val);
//另一个栈保存就好了,vector里不用
s.pop();
t.push(node);
if(node->left)
//注意改变了左和右
s.push(node->left);
if(node->right)
s.push(node->right);
while(!t.empty())
v.push_back(t.top()->val);
t.pop();
return v;
;
以上是关于数据结构二叉树遍历(前中后,递归非递归)的主要内容,如果未能解决你的问题,请参考以下文章