二叉树遍历

二叉树遍历

2024年7月27日

21:39

 

非递归版本

 

树结点结构

leetcode树结点结构

structTreeNode{

intval;

TreeNode*left;

TreeNode*right;

TreeNode():val(0),left(nullptr),right(nullptr){}

TreeNode(intx):val(x),left(nullptr),right(nullptr){}

TreeNode(intx,TreeNode*left,TreeNode*right):val(x),left(left),right(right){}

};

  1. 先序遍历
    1. 创建一个栈s,把头结点head入栈
    2. 只要栈中还有数据
      1. 取出栈顶数据,作为当前要操作的结点
      2. 处理后,先入右节点(不为空),再入左节点(不为空)
  2. 中序遍历,左中右
    1. 创建一个栈s,结点指针p遍历树;s用于压入当前树的头结点保存数据,p用于指向树节点做处理
    2. 只要栈不为空(说明还有被保存的结点没有被操作),并且p还指向着待处理的结点
      1. p不为空,就一直压入栈,并持续往左子树递进。(处理左子树)
      2. 遇到空,取栈顶元素操作(中),并让p指向栈顶元素的右子树(右子树)。
    3. 代码

classSolution{

public:

vector<int>inorderTraversal(TreeNode*root){

if(!root)

returnvector<int>();

vector<int>ret;

stack<TreeNode*>s;

while(!s.empty()||root){

while(root){

s.push(root);;

root=root->left;

}

root=s.top();

s.pop();

ret.push_back(root->val);

root=root->right;

}

returnret;

}

};

 

  1. 后序遍历(单栈处理)
    1. 需要栈s保存待处理的结点,cur结点指向当前需要处理的结点,h指向已经遍历的结点,先把头结点入栈s
    2. cur获取栈顶元素,
      1. 如果cur的左子树存在且h不等于cur的左子树,那么说明左子树还没处理,把左子树压入s
      2. cur的右子树存在且h不等于cur右子树,说明右子树还没处理,把右子树压入s
      3. 其他情况(左右子树微空或者均被遍历过),那么操作cur,h = cur,出栈顶元素。

classSolution{

public:

vector<int>postorderTraversal(TreeNode*root){

if(!root)

returnvector<int>();

vector<int>ret;//返回值

stack<TreeNode*>s;//保留现场

s.push(root);

TreeNode*h=root;//保留刚刚处理的结点

TreeNode*cur=nullptr;//当前节点

while(!cur||!s.empty()){

cur=s.top();

if(cur->left&&

cur->left!=h&&

cur->right!=h){//有左子树且左树没处理,开始处理左子树

s.push(cur->left);

}

elseif(cur->right

&&cur->right!=h){//左树存在且已经没处理,开始处理右

s.push(cur->right);

}

else{//左右均不存在或被处理

ret.push_back(cur->val);

h=cur;

s.pop();

}

}

returnret;

}

};

 

posted @ 2024-07-31 21:07  刘?  阅读(4)  评论(0编辑  收藏  举报