leetcode: Binary Tree Preorder Traversal

本文详细介绍了二叉树的遍历方法,包括先序、中序和后序遍历的递归与非递归实现。重点讲解了后序遍历的非递归实现,并提供了一种使用栈来辅助实现的具体算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a binary tree, return the preorder traversal of its nodes' values.

For example:
Given binary tree {1,#,2,3},

   1
    \
     2
    /
   3

return [1,2,3].

Note: Recursive solution is trivial, could you do it iteratively?

本题为二叉树的先序遍历,也就是先根遍历,但是提示不能用递归,所以就是二叉树先序遍历的非递归实现。现在为了在面试中能够灵活的掌握非递归遍历,三种遍历方法都总结一下,方面以后的面试中复习使用。

先序遍历:

  递归:

void traverse(Tree *root)
{
       if(root==NULL) return;
       visit(root->data);
       traverse(Tree->left);
       traverse(Tree->right);
}
非递归(用栈实现,是因为递归的过程就是程序自动压栈);

void traverse(Tree *root)
{
       stack.push(root);
       while(!stack.empty())
     {
              temp=stack.top();
              stack.pop();
              visit(temp->data);
              stack.push(temp->right);//先将右儿子入栈,因为比左儿子更晚访问到
              stack.push(temp->left);
     }
}
中序遍历:

递归:

 void   traverse(Tree *root){

                if(root==NULL)    return;

                traverse(Tree->left);

                visit(root->data);

                traverse(Tree->right);

        }                       
后序遍历:

递归:

 void   traverse(Tree *root){

                if(root==NULL)    return;

                traverse(Tree->left);


                traverse(Tree->right);

                 visit(root->data);

        }                       
非递归1:
         后序遍历的非递归实现是三种遍历方式中最难的一种。因为在后序遍历中,要保证左孩子和右孩子都已被访问并且左孩子在右孩子前访问才能访问根结点,这就为流程的控制带来了难题。下面介绍两种思路。
      第一种思路:对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。

代码实现:
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        TreeNode* temp;
        stack<TreeNode *> st;
        st.push(root);
        while(!st.empty())
        {
            temp=st.top();
            st.pop();
            
            visit(temp->val);
            st.push(temp->right);
            st.push(temp->left);
        }
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值