数据结构复习之二叉树的非递归先序,中序,后序遍历

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;

struct Tree{
    int x;
    Tree *lchild, *rchild;
    Tree(){
        lchild = rchild = NULL;
    }
};

typedef Tree* pT;

void buildT(pT &T){
    int n;
    cin>>n;
    if(n==-1)
        return;
    T = new Tree();
    T->x = n;
    buildT(T->lchild);
    buildT(T->rchild);
}
/**************************************************************************/
/*
     非递归先序遍历: 对于任一结点P:

     1)访问结点P,并将结点P入栈;

     2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,    循环至1); 若不为空,则将P的左孩子置为当前的结点P;

     3)直到P为NULL并且栈为空,则遍历结束。
*/
void preOrderNorecursive(pT T){
    stack<pT> s;
    s.push(T);
    while(!s.empty()){
        while(T != NULL){//左子树走到尽头
            cout<<T->x<<" ";
            T = T->lchild;
            s.push(T);
        }
        s.pop();//清除空指针
        if(!s.empty()) {
            T = s.top();
            s.pop();
            s.push(T=T->rchild);//右子树走起
        }
    }
}

void preOrderOutT(pT T){
    if(T){
        cout<<T->x<<" ";
        preOrderOutT(T->lchild);
        preOrderOutT(T->rchild);
    }
}

/**************************************************************************/
/*
   非递归中序遍历:对于任一结点P,

  1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;

  2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;

  3)直到P为NULL并且栈为空则遍历结束
*/
void inOrderNorecursive(pT T){
    stack<pT> s;
    s.push(T);
    while(!s.empty()){
         while(T!=NULL)//左子树走到尽头
             s.push(T=T->lchild);
         s.pop();//清除空指针
         if(!s.empty()) {
             T = s.top();
             s.pop();
             cout<<T->x<<" ";
             s.push(T = T->rchild);//访问右子树
         }
    }
}

void inOrderOutT(pT T){
    if(T){
        inOrderOutT(T->lchild);
        cout<<T->x<<" ";
        inOrderOutT(T->rchild);
    }
}

/**************************************************************************/
/*
    非递归后序遍历:
        要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。
    如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子
    都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,
    这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
*/
void postOrderNorecursive(pT T){
    stack<pT> s;
    s.push(T);
    pT pre = NULL;//后序遍历之前输出的节点
    while(!s.empty()){
        T = s.top();
        if(T->lchild==NULL && T->rchild==NULL ||
           T->lchild==pre || T->rchild==pre) {
           cout<<T->x<<" ";
           pre = T;
           s.pop();
        } else {//依次将右子树和左子树放入栈中
            if(T->rchild)
                s.push(T->rchild);
            if(T->lchild)
                s.push(T->lchild);
        }
    }
}

void postOrderOutT(pT T){
    if(T){
        postOrderOutT(T->lchild);
        postOrderOutT(T->rchild);
        cout<<T->x<<" ";
    }
}
/**************************************************************************/ 

int main(){
    pT T = NULL;
    buildT(T);
    /**************************************************************************/
    cout<<"递归先序遍历:"<<endl;
    preOrderOutT(T);
    cout<<endl;
    cout<<"非递归先序遍历:"<<endl;
    preOrderNorecursive(T);
    cout<<endl;
    /**************************************************************************/
    cout<<"递归中序遍历:"<<endl;
    inOrderOutT(T);
    cout<<endl;
    cout<<"非递归中序遍历:"<<endl;
    inOrderNorecursive(T);
    cout<<endl;
    /**************************************************************************/
    cout<<"递归后序遍历:"<<endl;
    postOrderOutT(T);
    cout<<endl;
    cout<<"非递归后序遍历:"<<endl;
    postOrderNorecursive(T);
    cout<<endl;
    /**************************************************************************/
    return 0;
}/*

1 2 2 -1 -1 4 7 -1 -1 -1 3 4 -1 8 -1 -1 5 -1 -1
递归先序遍历:
1 2 2 4 7 3 4 8 5
非递归先序遍历:
1 2 2 4 7 3 4 8 5
递归中序遍历:
2 2 7 4 1 4 8 3 5
非递归中序遍历:
2 2 7 4 1 4 8 3 5
递归后序遍历:
2 7 4 2 8 4 5 3 1
非递归后序遍历:
2 7 4 2 8 4 5 3 1

*/
时间: 2024-12-13 07:37:35

数据结构复习之二叉树的非递归先序,中序,后序遍历的相关文章

二叉树遍历算法——包含递归前、中、后序和层次,非递归前、中、后序和层次遍历共八种

首先,要感谢网上的参考资料. http://mengliao.blog.51cto.com/876134/1178079(作者:BlackAlpha) http://blog.csdn.net/fzh1900/article/details/14056735(作者:_云淡风轻) http://blog.csdn.net/stpeace/article/details/8138458(作者:stpeace) 二叉树是使用的比较广泛的一种数据结构,这里我写了二叉树的相关操作,包括初始化.新建.以及遍

树的遍历总结 (包括递归,非递归),轻松理解后序遍历

参考大神的神作:http://blog.csdn.net/fightforyourdream/article/details/16843303 对于后序遍历,我们理解为将右节点为先的先序遍历翻转,会思考上简单很多,就是用右节点为先的先序遍历做,再用第二个栈进行翻转,就是后序遍历.

【C语言】【数据结构】菜鸟学习日志(四) 用二叉树实现非递归排序

唉,由于要备战考研,这篇博文可能是我这一年最后一次更新啦! 其实断断续续的也没有写很多,而且大多都是很初级.很简单的东西,没有和大家分享什么高阶的东西.这也正应了我们<菜鸟学习日志>的标题嘛! 不过说回来我还是很喜欢写博文的.一方面总结学到的知识,以后也可以自己看看别做了就忘了:另一方面,写博文也让我在学习的过程中更加认真,以免分享了错误的知识. 写的东西好不好呢是一说,好像有一些点击量,不过看的人估计也不多.只是我还算乐在其中吧! 大学生活说到底过得有点浪了,导致我苦逼地走向了考研的不归路-

二叉树的非递归遍历--京东2015笔试回忆

题目回忆: C/C++研发试卷:偏重于数据结构的考察,编程题有2题+1题附加题: 1.输入整数n,求m,m>9,m中各个数位的乘积=n的最小整数;如n=36,m=49; 2.二叉树前序遍历的非递归实现(本文的总结) 3.求第n个数,这个序列满足(2^i)*(3^j)*(5^k),前7个为:2,3,4,5,6,8,10 .... 小题有基本的数据结构.程序运行结果.SQL题目. 4.删除表格用DROP命令,死锁产生的条件: 4.1互斥使用(资源独占) 一个资源每次只能给一个进程使用 4.2.不可强

二叉树的非递归遍历及算法分析

二叉树介绍 二叉树是一类重要的数据结构.二叉树常被用于实现二叉查找树和二叉堆.通常子树被称作"左子树"(left subtree)和"右子树"(right subtree). 一种二叉树结点定义: struct bit_node { chardata; structbit_node *lchild,*rchild; }; 遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次.由于二叉树是

二叉树的非递归遍历(转)

原文地址 二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁.而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现.在三种遍历中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对来说要难一点. 一.前序遍历 前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问. 1.递归实现 void pr

二叉树的非递归遍历C语言实现

腾讯面试中被问到二叉树的非递归遍历实现,当时记得不太清楚,回来专门复习了非递归的实现,整理代码如下: //采用二叉链表存储方式的二叉树,非递归中序遍历C语言实现代码 #include<stdio.h> #include <malloc.h> //函数结果状态代码 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 //Status是

(转)二叉树的非递归遍历

转自: 二叉树的非递归遍历 http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html 二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁.而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现.在三种遍历中,前序和中序遍历的非递归算法都

二叉树的非递归遍历(转载)

二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁.而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现.在三种遍历中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对来说要难一点. 一.前序遍历 前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问. 1.递归实现 void preOrde