二叉树非递归访问

二叉树非递归访问,借助一个栈,来模拟递归调用过程。

?





1

2

3

4

5

6

struct
TreeNode {

     char
val;

     TreeNode *left;

     TreeNode *right;

     TreeNode(int
x) : val(x), left(NULL), right(NULL) {}

 };

1. 先序遍历

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

void
PreOrder(TreeNode *root)

{

    if
(root == NULL)

        return;

    stack<TreeNode*> s;

    s.push(root);

    while
(!s.empty())

    {

        TreeNode *node = s.top();

        s.pop();

        if
(node->right != NULL)

            s.push(node->right);

        if
(node ->left != NULL)

            s.push(node->left);

        cout << node->val << " ";

    }

    

}

2. 中序遍历

中序遍历,有一个很有意思的规律,从左子树返回,就要访问根节点。

所以,记录一下当前访问状态是下降(访问左子树)状态,还是从左子树返回状态。

从左子树返回后,要访问根节点,同时,如果根节点有右子树,要访问右子树。

右子树访问结束后,整棵访问完的子树又相当于一个左子树。

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

void
InOrder(TreeNode *root)

{

    if
(root == NULL)

        return;

    stack<TreeNode*> s;

    s.push(root);

    TreeNode *prev = NULL;

    while
(!s.empty())

    {

        TreeNode *curr = s.top();

                //当前是下降过程

        if
(!prev || prev->left == curr || prev->right == curr)

        {

            if
(curr->left != NULL)

                s.push(curr->left);

        }

        else 
// 从左子树返回

        {

            s.pop();

            cout << curr->val << " ";

            if
(curr->right != NULL)

                s.push(curr->right);

        }

        prev = curr;

    }

}

3. 后序遍历

后序遍历,要在第二次返回的时候访问根节点。

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

void
PostOrder(TreeNode *root)

{

    if
(root == NULL)

        return;

    stack<TreeNode*> s;

    s.push(root);

    TreeNode *prev = NULL;

    TreeNode *curr = NULL;

    while
(!s.empty())

    {

        curr = s.top();

        if
(!prev || prev->left == curr || prev->right == curr)

        {

            if
(curr->left != NULL)

                s.push(curr->left);

            else
if (curr->right != NULL)

                s.push(curr->right);

        }

        else
if (curr->left == prev) //左子树返回

        {

            if
(curr->right != NULL)

                s.push(curr->right);

        }

        else                        
//从右子树返回 或 无右子树

        {

            s.pop();

            cout << curr->val << " ";

        }

        prev = curr;

    }

}

比较简单的一种后序访问就是采用双栈策略。

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

void
PostOrder(TreeNode *root)

{

    if
(root == NULL)

        return;

    stack<TreeNode*> s;

    stack<TreeNode*> result;

    TreeNode *curr = NULL;

    s.push(root);

    while
(!s.empty())

    {

        curr = s.top();

        s.pop();

        result.push(curr);

        if
(curr->left != NULL)

            s.push(curr->left);

        if
(curr->right != NULL)

            s.push(curr->right);

    }

    while
(!result.empty())

    {

        curr = result.top();

        result.pop();

        cout << curr->val << " ";

    }

}

按照后序遍历的顺序,将最后要访问的结点压入result栈的栈底。

  

二叉树非递归访问,布布扣,bubuko.com

时间: 2024-12-19 23:41:59

二叉树非递归访问的相关文章

【LeetCode-面试算法经典-Java实现】【145-Binary Tree Postorder Traversal(二叉树非递归后序遍历)】

[145-Binary Tree Postorder Traversal(二叉树非递归后序遍历)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 2 / 3 return [3,2,1]. Note: Recursive soluti

二叉树非递归先中后序遍历 及 非递归交换二叉树两个孩子的位置

看到一个非递归交换一个二叉树的左右孩子的位置,于是想实现之,才发现非递归的先中后序遍历都忘记了……于是杂七杂八的写了一些,抄抄资料就实现了,然后实现非递归交换两个孩子的位置还是相当容易的.先直接上代码吧,其实这东西还是得自己写写过一遍的,印象才会更加深刻: #include <iostream> #include <fstream> #include <string> #include <stack> using std::cout; using std::

Best Coder Round#25 1003 树的非递归访问

虽然官方解释是这题目里的树看作无向无环图,从答案来看还是在“以1作为根节点”这一前提下进行的,这棵树搭建好以后,从叶节点开始访问,一直推到根节点即可——很像动态规划的“自底向上”. 但这棵树的搭建堪忧:给出的边不知道哪边更接近根节点.所以我给出的方案干脆在两个顶点都将对方加成孩子,等到访问的时候再作处理,根据从1这个根节点开始访问这个特性,额外加一个“isVisited"来做区分. 然后利用栈对树进行非递归访问 /** * For best-coder problem 3 */ #include

JumpNode递归和非递归访问

JumpNode的定义结构为如下所示: struct JumpNode { int data; //存储数据 int order; // 记录访问次序,初始化均为0 JumpNode *jump, *next; // next为线性下一节点,jump为跳跃到下一节点 JumpNode(int d): data(d), order(-1), jump(NULL), next(NULL) {} }; 现在需要以递归和非递归的方式来访问到一个JumpNode *list.在访问的时候给各个节点的ord

【LeetCode-面试算法经典-Java实现】【144-Binary Tree Preorder Traversal(二叉树非递归前序遍历)】

[144-Binary Tree Preorder Traversal(二叉树非递归前序遍历)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 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

二叉树非递归后缀遍历

二叉树的遍历方法可分为深度优先和广度优先两种.当中深度优先遍历适合使用栈来辅助实现.广度优先则使用队列.由于栈的先进后出和队列的先进先出特点正好符合遍历顺序的要求. 深度优先遍历一般又分为前序遍历,中序遍历.后序遍历,对于一颗树来说,前序.中序.后序针对的都是它的根节点.当中前序遍历訪问顺序是:根节点-->左节点-->右节点,中序遍历訪问顺序是:左节点-->根节点-->右节点,兴许遍历訪问顺序是:左节点-->右节点-->根节点.二叉树的结构是递归的,因此非常适合使用递归

二叉树非递归遍历

算法导论:10.4-3 给定一个 n 结点的二叉树,写出一个 O(n) 时间的非递归过程,将该树每个结点的关键字输出.可以使用一个栈作为辅助数据结构. 栈的实现参考这里. #ifndef _BINARY_TREE_USE_STACK_H_ #define _BINARY_TREE_USE_STACK_H_ /************************************************** 算法导论:10.4-3 给定一个 n 结点的二叉树,写出一个 O(n) 时间的非递归过程

数据结构之二叉树篇卷三 -- 二叉树非递归遍历(With Java)

Nonrecursive Traversal of Binary Tree First I wanna talk about why should we use <code>Stack</code> to implement this algorithm. I think it is due to the FILO feature of Stack, and that really matters and makes sense when you get around with t

Leetcode: Binary Tree Preorder Traversal(二叉树非递归前序遍历)

题目: 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? 二叉树的前序遍历 先看递归的写法(C++): /** * Definition f