【数据结构】 非递归前中后序遍历二叉树

数据结构学的递归了,深入了解后写一个三序非递归的版本。

//测试数据:abd##eg##h##c#f##
#include <cstdio>
#include <iostream>
typedef char ElemType;
typedef struct Node
{
    ElemType elem;
    struct Node *lchild,*rchild;
}Node,*BiTree;
typedef struct{
    BiTree *base;
    BiTree *top;
    int stacksize;
}SqStack;
void InitStack(SqStack &S)
{
    S.base=(BiTree *)malloc(100*sizeof(BiTree));
    if(!S.base) exit(0);
    S.top=S.base;
    S.stacksize=100;
}
void GetTop(SqStack S,BiTree &e)
{
    if(S.top==S.base)exit(0);
    e=*(S.top-1);
}
void Pop(SqStack &S,BiTree &e)
{
    if(S.top==S.base)exit(0);
    e=*--S.top;  //先自减,再取值
}
void Push(SqStack &S,BiTree e)//严谨的话还应该有if(S.top-S.base>=S.stacksize)的判断,此处略去
{
    *S.top++=e;//先赋值,再自加
}
int Empty(SqStack S)
{
    if(S.top==S.base)return 1;
    else return 0;
}
BiTree CreateTree(BiTree &T)
{
    char ch;
    ch=getchar();
    if(ch==‘#‘)T=NULL;
    else
    {
        T=(BiTree)malloc (sizeof(Node));
        T->elem=ch;
        T->lchild=(CreateTree(T->lchild));
        T->rchild=(CreateTree(T->rchild));
    }
    return T;
}
void Middleordertraverse(BiTree T) //中序非递归遍历
{
    SqStack S;
    InitStack(S);
    BiTree p=T;
    while(p || !Empty(S))
    {
        if(p)
        {
            Push(S,p);
            p=p->lchild;
        }
        else
        {
            Pop(S,p);
            printf("%c   \n",p->elem);
            p=p->rchild;
        }
    }
}
void Firstordertraverse(BiTree T)//先序非递归遍历
{
    SqStack S;
    InitStack(S);
    BiTree p=T;
    while(p || !Empty(S))
    {
        while(p)
        {
            Push(S,p);
            printf("%c   \n",p->elem);
            p=p->lchild;
        }
        if(!Empty(S))
        {
            Pop(S,p);
            p=p->rchild;
        }
    }
}
void BehindorderTraverse(BiTree T) //后序非递归遍历
{
    SqStack S;
    InitStack(S);
    BiTree pre;//设置标志位,标记是否访问过
    BiTree p=T;
    while(p || !Empty(S))
    {
        while(p)  //左孩子向下压栈  直到最左下
        {
            Push(S,p);
            p=p->lchild;
        }
        GetTop(S,p);   //取当前栈顶  即当前节点最左下
        if(!p->rchild || p->rchild==pre)//没右孩子或右孩子被遍历过
        {
            printf("%c   \n",p->elem);
            pre=p; //标记此节点已经走过
            Pop(S,p);
            if( Empty(S))return ;
            //p回到其父节点(前面肯定了没左子树,而进入此循环显然没右孩子)
            p=NULL;  //不对p左子树遍历
        }
        else p=p->rchild;
    }
    return ;
}
int main()
{
    //freopen("in.txt","r",stdin);
    printf("请给出二叉树的节点序列:  \n");
    BiTree T;
    CreateTree(T);
    printf(" 中序遍历二叉树结果是 :  \n");
    Middleordertraverse(T);
    printf(" 先序遍历二叉树结果是 :  \n");
    Firstordertraverse(T);
    printf(" 后序遍历二叉树结果是 :  \n");
    BehindorderTraverse(T);
    return 0;
}
时间: 2024-10-12 22:10:23

【数据结构】 非递归前中后序遍历二叉树的相关文章

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

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 写在前面: 最近准备找工作,捡起原来学习过的各种知识,加上一些自己的理解,梳理一下流程,巩固自己的认识,一步两步,一步两步... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 二叉树的遍历是树操作的基础,一般的前中后序递归遍历比较简单,这里就不列出了,主要是非递归实

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

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

二叉树的前中后序遍历简单的递归

二叉树的遍历 无外乎广度和深度 其中深度又分为前中后序遍历三种情况  这三种遍历若只是递归方法 自然很是简单 但递归代码简单 若嵌套层次太深 会栈溢出 二叉树节点数据结构: struct Binary_node{    int val;    Binary_node *left;    Binary_node *right;    Binary_node(int v = 0, Binary_node *le = nullptr, Binary_node *ri = nullptr) :val(v

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

二叉树的前序建立递归算法以及前中后序遍历的递归算法已经是人尽皆知了,递归算法也确实为代码的编写带来了很大的方便.然而,有时我们也确实需要它们的非递归算法.将递归算法转化为非递归算法可以帮助我们深入了解函数的调用与栈的原理.这里总结一下二叉树的这些重要的非递归算法. 一.前序建树 前序建树的基本思路是,接收用户输入的一组字符串,其中'#'代表空树,其他代表树结点的数据域值.例如,要建立如下一棵树 需要输入"AB#D##C##". 而非递归的思路是,1.设一个标志位来判断当前创建的结点是左

二叉树的前中后序遍历

#include<stdio.h> #include<string.h> #include<stdlib.h> #define Size 100 #define Resize 10 typedef struct Bitnode{ //定义结点 char data; struct Bitnode *lchild,*rchild; }Bitnode,*Bitree; typedef struct Stack{ //定义栈 Bitree *base; int top; int

二叉树系列 - 二叉树的前/中/后序遍历(非递归)

二叉树的遍历是二叉树中最最基础的部分. 这里整理二叉树不用递归实现三种顺序遍历的方式. 不用递归的话,一般需要栈来完成.当然线索二叉树(不需要栈或递归)也可以完成中序遍历,这种方式在这篇文章中已经讨论过.这里着重讨论使用栈的实现方式. 中序遍历 (1) 双while,第二个内层while是为了不断压入left child. vector<int> inorderTraversal(TreeNode *root) { vector<int> v; if(!root) return v

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

由于所有的递归算法都可以借助于堆栈转换成循环结构的非递归算法.方法一:形式化模拟转换.方法二:根据要求解问题的特点设计借助于堆栈的循环结构算法.而此次正好是利用第二种按方法求解. 1.1非递归前序遍历: 首先利用下图来设计非递归前序遍历算法思想: 堆栈结构体如下: #define size 100 typedef struct { DataType data[size]; int tag[100]; //这个是在非递归后序中用到 int top : }SeqStack : (1)初始化设置一个堆

二叉树的前中后序遍历迭代&amp;广度遍历

递归很是简单 但也应该掌握其迭代方式的遍历方法 这三种的迭代遍历方法需要通过栈来存储节点 尤其是后序遍历还需要 记录当前节点的右子树是否已被遍历 决定是否遍历当前节点 而其广度遍历 只需要一个队列来顺序记录遍历节点 即可轻松解决问题  主要思想在程序代码中来做说明 前序遍历:遍历结果返回一个vector容器中 std::vector<int> BinaryTree::pre_order_iter(Binary_node *root){    std::vector<int> res

树的前中后序遍历和层次遍历

遍历规则 前序遍历:根结点 ---> 左子树 ---> 右子树 中序遍历:左子树---> 根结点 ---> 右子树 后序遍历:左子树 ---> 右子树 ---> 根结点 层次遍历:只需按层次遍历即可 注: 1.前序.中序.后序属于深度优先遍历(使用递归较为方便),层次遍历为广度优先遍历(一般实现需要借助其他数据结构的支撑,如下面的队列等). 2.中序遍历有个小技巧:对于给定的树,可以画垂线,从左到右即为中序遍历的次序. 代码实现 #include <iostrea