非递归二叉树前中后序遍历

原创 2017年03月28日 22:54:18

以前经常说:

系统栈爆了怎么办?

手写啊!!

然而并没有写过一次

这次数据结构课介绍了非递归的二叉树遍历算法,后序还没讲,先写了再说

先序遍历:

1.我的直观想法是先把右子树压进去,再把左子树压进去

2.然而书上给的做法有点不一样,是先压左子树压到底,弹出的时候把当前的右子树给压进去。事实上在先序遍历上来说这两种做法没什么区别,我的想法相当于在压左子树之前就直接先把右子树压进去了

中序遍历:

中序遍历的时候我的做法不是那么管用了,因为先序遍历根节点最先访问,而中序需要左子树弹回来才能访问根节点,所以必须得用类似上面做法2的一样的思路

后序遍历:

可以和先序遍历一样一次性把右左子树压进去,在访问根节点前判一下上一个访问的是不是根节点的左右儿子,也就是说是不是从访问完左右儿子之后弹回来的,或者根本没有左右儿子,满足两种情况之一才能将这个点弹出来并访问,同时更新pre为这个根节点

void preOrder1(BiTree root) {
    stack <BiTree> s;
    BiTree p = root;
    while (p != NULL || !s.empty()) {
        while (p != NULL) {
            visit(p);
            s.push(p);  //prepare the traversal for the p's right child
            p = p -> lchild;
        }
        if (!s.empty()) {
            p = s.top();    //get the node
            s.pop();
            p = p -> rchild;    // turn to right child
        }
    }
}

void preOrder2(BiTree root) {
    stack <BiTree> s;
    BiTree p = root;
    while (!s.empty()) {
        vist(p = s.top());
        s.pop();
        if (p -> rchild != NULL)
            s.push(p -> rchild);
        if (p -> lchild != NULL)
            s.push(p -> lchild);
    }
}

void inOrder(BiTree root) {
    stack <BiTree> s;
    BiTree p = root;
    while (p != NULL || !s.empty()) {
        while (p != NULL) {
            s.push(p);  //prepare the traversal for the p's right child
            p = p -> lchild;
        }
        if (!s.empty()) {
            visit(p = s.top());
            s.pop();
            push(s.rchild);
        }
    }
}

void postOrder(BiTree root) {
    stack <BiTree> s;
    BiTree p = root, pre = NULL;
    s.push(root);
    while (!s.empty()) {
        p = s.top();
        if ((p -> lchild == NULL && p -> rchild == NULL) || (pre != NULL && (pre == p -> lchild || pre == p -> rchild))) {  // come from child node
            visit(p);
            s.pop();
            pre = p;
        }
        else {
            if (p -> rchild != NULL)
                s.push(p -> rchild);
                if (p -> lchild != NULL)
                    s.push(p -> lchild);
        }
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载,蒟蒻的文章转出去有点恥ずかしい

二叉树前序、中序、后序遍历非递归写法的透彻解析

前言 在前两篇文章二叉树和二叉搜索树中已经涉及到了二叉树的三种遍历。递归写法,只要理解思想,几行代码。可是非递归写法却很不容易。这里特地总结下,透彻解析它们的非递归写法。其中,中序遍历的非递归写法最...
  • zhangxiangDavaid
  • zhangxiangDavaid
  • 2014年07月06日 22:14
  • 63854

算法:二叉树的先序遍历、中序遍历、后序遍历(递归及非递归方式)的java代码实现

首先来看一棵二叉树: 1、前序遍历: 前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树...
  • jssongwei
  • jssongwei
  • 2016年03月03日 17:33
  • 6611

二叉树递归非递归遍历(递归前中后,非递归前中后,层次遍历,凹入打印法等)

由于所有的递归算法都可以借助于堆栈转换成循环结构的非递归算法。方法一:形式化模拟转换。方法二:根据要求解问题的特点设计借助于堆栈的循环结构算法。而此次正好是利用第二种按方法求解。1.1非递归前序遍历:...
  • xiaofei__
  • xiaofei__
  • 2016年05月30日 21:28
  • 3909

二叉树前、中、后序遍历【非递归】【LintCode测试平台】

定义节点 /** * Definition of TreeNode: * class TreeNode { * public: * int val; ...
  • silence_iz
  • silence_iz
  • 2016年08月04日 16:53
  • 134

二叉树前中后序遍历的递归版本和非递归版本、队列实现的层次遍历

/* 数据结构分析与学习专栏 * Copyright (c) 2015, 山东大学 计算机科学与技术专业 学生 * All rights reserved. * 作 者: 高祥...
  • gaoxiangnumber1
  • gaoxiangnumber1
  • 2015年04月12日 23:39
  • 337

【11】-java递归和非递归二叉树前序中序后序遍历

二叉树的遍历对于二叉树来讲最主要、最基本的运算是遍历。 遍历二叉树 是指以一定的次序访问二叉树中的每个结点。所谓 访问结点 是指对结点进行各种操作的简称。例如,查询结点数据域的内容,或输出它...
  • u010321471
  • u010321471
  • 2016年04月29日 00:31
  • 8903

二叉树前序、中序、后序遍历(递归版、非递归版)

复习二叉树的遍历,自己实现了一遍代码,在这里进行下记录,递归和非递归都写出来了,感谢各位的批评指正。节点定义:package com.al;public class Node { public ...
  • anl_studyroad
  • anl_studyroad
  • 2016年07月22日 08:47
  • 105

c语言实现二叉树的前中后序遍历 递归和非递归 数据结构

  • 2014年03月23日 20:51
  • 7KB
  • 下载

二叉树的非递归建立,前序、中序、后序遍历

  • 2017年07月17日 20:18
  • 5KB
  • 下载

二叉树前中后序遍历(递归)

中途对于递归总是理不清,后来看了代码和书才想通:递归==递+归:必须要有递归结束条件,可以不是返回值,若调用一个递归的主算法为第0层算法,则从主算法调用递归算法为进入第1层调用,从第i层递归调用本算法...
  • uagvdu
  • uagvdu
  • 2016年04月26日 09:36
  • 448
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:非递归二叉树前中后序遍历
举报原因:
原因补充:

(最多只允许输入30个字)