迭代遍历二叉树

二叉树的递归遍历很容易写出来,对于递归遍历则需要借助辅助栈,并且不同的遍历次序迭代的写法也不尽相同,这里整理一些二叉树迭代遍历的实现

二叉树的前序遍历

代码

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> stk;
        vector<int> ans;
        if(!root)  return ans;
        stk.push(root);
        while(!stk.empty()){ //当栈为空意味着所有结点都访问完毕了
            TreeNode* u = stk.top(); stk.pop();
            ans.push_back(u->val); //访问当前结点
            if(u->right != NULL) stk.push(u->right); //右孩子入栈
            if(u->left != NULL) stk.push(u->left);  //左孩子入栈,因为栈的后进先出性质,保证当前结点的左孩子先先于右孩子访问
        }
        return ans;
    }
};

二叉树的中序遍历

代码https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        stack<TreeNode*> stk;
        TreeNode* p = root;
        while(!stk.empty() || p != nullptr){
            if(p != nullptr){
                stk.push(p);
                p = p->left;   //一直向左走
            }else{             //找到一个最左的结点
                p = stk.top(); stk.pop();  //把这个结点弹出栈
                ans.push_back(p->val);     //访问
                p = p->right;              //然后从其右孩子出发
            }
        }
        return ans;
    }
};

二叉树的后序遍历https://leetcode-cn.com/problems/binary-tree-postorder-traversal/

代码

/*
因为后序遍历总是先访问结点的所有孩子,然后再访问结点自身,所以我们用一个boolean visit标记结点的孩子是否都入栈,当从栈顶弹出的结点的孩子还没访问时,继续访问其孩子,并标记visit,否则,就可以直接访问这个结点的值。我认为这种遍历方式在思维上是最为清晰的,只是我们需要用一个pair来组织结点及其孩子访问情况。
*/
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        stack<pair<TreeNode*, bool>> s;
        if(!root) return ans;
        s.push(make_pair(root, false));
        while(!s.empty()){
            auto& node = s.top();
            bool visited = node.second;
            if(!visited){
                if(node.first->right) s.push(make_pair(node.first->right, false));
                if(node.first->left) s.push(make_pair(node.first->left, false));
                node.second = true;
            }else{
                ans.push_back(node.first->val);
                s.pop();
            }
        }
        return ans;
    }
};

另一种后序遍历的迭代实现:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        stack<TreeNode*> s;
        TreeNode* p = root; TreeNode* q = nullptr;
        do{
            while(p != nullptr){
                s.push(p);
                p = p->left;
            }
            q = nullptr;
            while(!s.empty()){
                p = s.top(); s.pop();
                if(p->right == q){
                    ans.push_back(p->val);
                    q = p;
                }else{
                    s.push(p);
                    p = p->right;
                    break;
                }
            }
        }while(!s.empty());
        return ans;
    }
};

原文地址:https://www.cnblogs.com/patrolli/p/12285446.html

时间: 2024-10-08 13:15:55

迭代遍历二叉树的相关文章

【转载】Morris遍历二叉树 &amp; BST(二叉搜索树) Traverse &amp; 空间O(1) 时间O(n)

因为做一道Leetcode的题目(前面博客有:link),需要用Space O(1)空间复杂度来中序遍历树, 看了Discuss,也上网搜了一下,发现空间O(1)可以用 Morris遍历的方法.方法介绍如下: http://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html其中,中序遍历和前序遍历比较方便解决: 通常,实现二叉树的前序(preorder).中序(inorder).后序(postorder)遍历有两个常用

【转】更简单的非递归遍历二叉树的方法

解决二叉树的很多问题的方案都是基于对二叉树的遍历.遍历二叉树的前序,中序,后序三大方法算是计算机科班学生必写代码了.其递归遍历是人人都能信手拈来,可是在手生时写出非递归遍历恐非易事.正因为并非易事,所以网上出现无数的介绍二叉树非递归遍历方法的文章.可是大家需要的真是那些非递归遍历代码和讲述吗?代码早在学数据结构时就看懂了,理解了,可为什么我们一而再再而三地忘记非递归遍历方法,却始终记住了递归遍历方法? 三种递归遍历对遍历的描述,思路非常简洁,最重要的是三种方法完全统一,大大减轻了我们理解的负担.

LeetCode OJ:Binary Tree Inorder Traversal(中序遍历二叉树)

Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary tree {1,#,2,3}, 1 2 / 3 return [1,3,2]. Note: Recursive solution is trivial, could you do it iteratively?中序遍历二叉树,递归遍历当然很容易,题目还要求不用递归,下面给出两种方法: 递归: 1 /**

Leetcode 94. Binary Tree Inorder Traversal (中序遍历二叉树)

Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binary tree [1,null,2,3], 1 2 / 3 return [1,3,2]. Note: Recursive(递归) solution is trivial, could you do it iteratively(迭代)? 思路: 解法一:用递归方法很简单, (1)如果root为空,则返回NU

JAVA递归、非递归遍历二叉树(转)

原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private BinTree lchild; private BinTree rchild; public BinTree(char c) { date = c; } // 先序遍历递归 public static void preOrder(BinTree t) {

非递归实现遍历二叉树

非递归实现二叉树主要利用queue和stack的特点,对于层次遍历二叉树主要运用queue队头出,队尾插入,先进先出的特点,先将根插入队尾,然后输出队头的元素,同时将队头的左子树和右子树元素插入队尾,依次输出输出队头的元素,同时将队头的左子树和右子树元素插入队尾,直到队列为空. void levelorder() { queue<BinaryTreeNode<T> *>s; if (_root == NULL) return; s.push(_root); while (!s.em

递归遍历二叉树

递归遍历分三种: 1.前序遍历二叉树(二叉树非空) 1.访问根节点 2.前序遍历左子树 3.前序遍历右子树 2.中序遍历二叉树(二叉树非空) 1.中序遍历左子树 2.访问根节点 3.中序遍历右子树 3.后序遍历二叉树(二叉树非空) 1.后序遍历左子树 2.后序遍历右子树 3.访问根节点 三种递归的算法遍历,终止条件是二叉树为空的时候. 记忆的方法呢,前中后,都是以根节点命名的,前序,先访问根节点,中序,根节点在第二,后序,根节点最后进行访问.

TAOCP_2.3.1_遍历二叉树

1. 算法T(以中根序遍历二叉树) 设$T$是指向二叉树的指针:本算法以中根序访问二叉树中的所有节点,并且利用一个辅助栈A. T1. [初始化] 置栈A为空,并置链接变量$P \gets T$. T2. [$P=\bigwedge$?] 如果$P=\bigwedge$,转到步骤T4. T3. [$栈 \Leftarrow P$] (现在P指向要加以遍历的一个非空二叉树.)置 $A \Leftarrow P$:即是,把P的值放入栈A.然后置$P \to LLINK(P)$并返回步骤T2. T4.

数据结构(C实现)------- 遍历二叉树

本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 二叉树是另一中树型结构,它的特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒. 根据二叉树的的递归定义可知,二叉树是由3个基本单元组成,根结点.左子树和右子树,因此,若能依次遍历这三部分,便是遍历了整个二叉树.假如以L.D.R分别表示遍历左子树.访问根结点和遍历右子树,则可能有DLR.LDR.LRD.DRL.RD