关于二叉树遍历的一些思考

  今天在刷leetcode时,挑了二叉树的第一题来做。题目很简单,就是中序遍历二叉树,不过要求是得用循环的方式实现。
  二叉树最初是在本科学习数据结构时接触到的,现在已经基本忘光了。因此我翻了一下书,发现中序遍历的基本要求是:遍历左子树,根节点,右子树。初学者可能会混淆的一点,是将左子树和右子树当做左节点和右节点。换言之,遍历左子树,需要从左子树的根节点出发,再进行左子树->根节点->右子树的遍历过程。前序遍历和后序遍历的过程亦如是。
  言归正传。通常是通过递归调用的方法完成二叉树遍历,简单清晰。题目给出的要求,目的在于开拓新的思路。solution中给出了两种解法。
  方法一的基本思路和递归法基本是一致的。它先逐次向左遍历,直到为空,并用一个堆栈存储遍历的值,将最后一个节点的值插入保存结果的数组中,并将其推出。在最后一个节点处,可能有右子树存在,因此还需要再对其进行向左遍历。结束后,堆栈自底向上存储着根节点的值。依次将其推出,并重复以上过程可得到中序遍历的结果。在https://leetcode.com/problems/binary-tree-inorder-traversal/solution/ 中有详细的动画演示和说明,此处不再赘述。我试着用这种方式完成二叉树的后序遍历,代码如下:

class Solution {
public:
    vector<int> inorderTraversal(TreeNode *root) {
    vector<int> res;
    TreeNode *p=root,*pre=NULL;  //pre记录前一遍历节点
    stack<TreeNode> temp;
    temp.push(*p);  //根节点入栈
    while(!temp.empty())
    {
        p=&(temp.top());
        if((p->left==NULL&&p->right==NULL)||(pre!=NULL&&(pre==p->left||pre==p->right)))
        {
            res.push_back(p->val);
            temp.pop();  //出栈
            pre=p;  
        }
        else  //将右节点、左节点依次入栈
        {
            if(p->right!=NULL)
                temp.push(*p->right);
            if(p->left!=NULL)
                temp.push(*p->left);
        }
    }
    return res;
    }
};

  方法二称为Morris遍历,它的做法比较独特,同样在上面的链接中有说明。具体不再阐述。
  

猜你喜欢

转载自blog.csdn.net/xbb123456rt/article/details/77895545