建立二叉树,实现二叉树的先序遍历、中序和后序遍历的非递归算法

先序遍历:若二叉树为空,则空操作;否则访问根节点;先序遍历左子树;先序遍历右子树。
中序遍历:若二叉树为空,则空操作;否则中序遍历左子树;访问根节点;中序遍历右子树。
后序遍历:若二叉树为空,则空操作;否则后序遍历左子树;后序遍历右子树;访问根节点。

/*
* Created by Microsoft Visual Studio 2013
* @author: Teresa
* @date: 2017-10-22
* @description: 二叉树遍历 非递归 
*/

#include <stdio.h>
#include <stdlib.h>
/*函数状态码*/
#define TRUE 1	//成功
#define OK 1
#define FALSE 0	//失败 
#define ERROR 0	//错误 
#define INFEASIBLE -1	//不可行的
#define OVERFLOW -2 	//溢出

typedef int Status;	//函数的返回值类型 
 
//二叉树的二叉链表存储表示
typedef char TElemType;
typedef struct BiNode{
    TElemType data;
    struct BiNode *lchild, *rchild;
} BiNode , *BiTree;
 
//栈的顺序存储结构
#define STACK_INIT_SIZE 100      //存储空间初始分配量
#define STACKINCREMENT 10       //存储空间分配增量
 
typedef struct{
    BiTree *base;
    BiTree *top;
    int stacksize;
} Stack;

//初始化栈
Status InitStack(Stack *s){
    s->base = (BiTree*)malloc(sizeof(BiTree)*STACK_INIT_SIZE);
    s->top = s->base;
    s->stacksize = STACK_INIT_SIZE;
    return OK;
}

//判断栈是否为空
Status StackEmpty(Stack *s){
    if (s->base == s->top)
        return OK;
    return ERROR;
}
 
//获得栈顶元素
Status GetTop(Stack *s, BiTree *c){
    if (StackEmpty(s))
        return ERROR;
    *c = *(s->top - 1);
    return OK;
}
 

//进栈
Status Push(Stack *s, BiTree c)
{
    //如果空间不够,增加空间的分配
    if (s->top - s->base >= s->stacksize){
        s->base = (BiTree*)realloc(s->base, sizeof(BiTree)*(s->stacksize + STACKINCREMENT));
        s->stacksize = s->stacksize + STACKINCREMENT;
    }
 
    *(s->top++) = c;
    return OK;
}
 
//出栈
Status Pop(Stack *s, BiTree *c){
    if (StackEmpty(s))
        return ERROR;
    *c = *(--s->top);
    return OK;
}
 
//遍历数据元素时所调用函数
Status PrintElement(TElemType e){
    putchar(e);
    return OK;
}
  

//按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树,构造二叉链表表示的二叉树T。
Status CreatBiTree(BiTree *T){
    char ch;
    scanf("%c", &ch);
 
    //如果当前输入的字符为空格,则(*T)指向空树。
    if (ch == ' '){
        (*T) = NULL;
    }
    else{
        if (!((*T) = (BiTree)malloc(sizeof(BiNode))))
            exit(OVERFLOW);
        (*T)->data = ch;             //生成根结点
        CreatBiTree(&((*T)->lchild));    //构造左子树
        CreatBiTree(&((*T)->rchild));    //构造右子树
    }
    return OK;
}

 
//先序遍历二叉树,非递归算法。
Status PreOrderTraverse_NonRecursive(BiTree T, Status(*Visit)(TElemType e)){
    Stack *S;   //栈S中存储指向树结点的指针。
    BiTree p;
    S = (Stack*)malloc(sizeof(Stack));
    InitStack(S);
    Push(S, T); //根指针进栈。
    while (!StackEmpty(S)){
        //获取栈顶指针,如果栈顶指针不为空,访问该结点。并将该结点的左子树进栈。
        if (GetTop(S, &p) && p){
            if (!Visit(p->data))
                return ERROR;
            Push(S, p->lchild);
        }
        //栈顶指针为空,表明之前压入的左子树或者右子树为空。
        else{
            Pop(S, &p); //空指针退栈
            if (!StackEmpty(S)){
                Pop(S, &p); //已被访问过的根结点退栈。此时,该退栈结点的左子树已被全部访问过。
                Push(S, p->rchild);  //右子树进栈。
            }
        }
    }
    return OK;
}
 
 
//采用二叉链表存储结构,Visit是对数据元素进行操作的应用函数,
//中序遍历二叉树的非递归算法,对每个数据元素调用函数Visit。
Status InOrderTraverse_NonRecursive(BiTree T, Status(*Visit)(TElemType e)){
    Stack *S;
    BiTree p;
    S = (Stack *)malloc(sizeof(Stack));
    InitStack(S);
    Push(S, T); //根指针进栈
    while (!StackEmpty(S)){
        //向左走到尽头
        while (GetTop(S, &p) && p){
            Push(S, p->lchild);
        }
 
        //空指针退栈
        Pop(S, &p);
        //访问节点,并向右一步
        if (!StackEmpty(S)){
            Pop(S, &p);
            if (!Visit(p->data))
                return ERROR;
            Push(S, p->rchild);
        }
    }
    return OK;
}
 

//采用二叉链表存储结构,Visit是对数据元素进行操作的应用函数,
//中序遍历二叉树的非递归算法,对每个数据元素调用函数Visit。
Status InOrderTraverse_NonRecursive_2(BiTree T, Status(*Visit)(TElemType e))
{
    Stack *S;
    BiTree p = T;
    S = (Stack *)malloc(sizeof(Stack));
    InitStack(S);
    while (p || !StackEmpty(S)){
        //根指针进栈,遍历左子树
        if (p){
            Push(S, p);
            p = p->lchild;
        }
        //根指针退栈,访问根结点,遍历右子树
        else{
            Pop(S, &p);
            if (!Visit(p->data))
                return ERROR;
            p = p->rchild;
        }
    }
    return OK;
}
 
//后序遍历二叉树,非递归算法
Status PostOrderTraverse_NonRecursive(BiTree T, Status(*Visit)(TElemType e)){
    Stack *S;
    BiTree p, pre=NULL;//pre指向已访问过的最后一个结点。
    S = (Stack*)malloc(sizeof(Stack));
    InitStack(S);
    Push(S, T);//根指针进栈
    while (!StackEmpty(S)){
        //获取栈顶指针,如果当前结点有左子树,并且左子树结点不是刚被访问的节点。如果当前结点有右子树,并且右子树结点不是刚被访问的结点。
        //表明栈顶指针指向的树结点未被访问,且左子树和右子树均未被访问。此时,将结点的左子树进栈。
        if (GetTop(S, &p) && p->lchild && pre != p->lchild && !(p->rchild && pre == p->rchild))
            Push(S, p->lchild);
        //如果栈顶指针的右子树存在,且未被访问。则将右子树进栈
        else if (p->rchild && pre != p->rchild)
            Push(S, p->rchild);
//如果左子树和右子树均被访问过,则结点退栈,并进行访问。更新pre。
        else{
            Pop(S, &p);
            if (!Visit(p->data))
                return ERROR;
            pre = p;
        }
    }
    return OK;
}

int main()
{
    BiTree T;
    CreatBiTree(&T);
    //先序
    printf("先序:\n");
    PreOrderTraverse_NonRecursive(T, PrintElement);
    printf("\n");
    //中序
	printf("中序:\n"); 
    InOrderTraverse_NonRecursive(T, PrintElement); 
    printf("\n");
    InOrderTraverse_NonRecursive_2(T, PrintElement);
    printf("\n");
    //后序
    printf("后序:\n"); 
    PostOrderTraverse_NonRecursive(T, PrintElement);
    printf("\n");
    system("pause");
    return 0;
}

《建立二叉树,实现二叉树的先序遍历、中序和后序遍历的非递归算法》

    原文作者:递归算法
    原文地址: https://blog.csdn.net/qq_36894136/article/details/78381380
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞