数据结构——二叉树的先序、中序遍历(非递归)

二叉树的先序、中序非递归遍历用到的是栈,创建二叉树时用的是递归的方法。在先序、中序遍历时用栈来存储结点。

先序遍历:首先,创建一个指针p指向二叉树的树根,输出p指向的结点的数据,然后将p压入栈中并让p指向其左孩子,直到p指向的结点为NULL。然后令栈中存的结点指针出栈,并让其指向其右孩子,若不为空,则输出数据。直到栈为空,结束。此时就完成了二叉树的先序遍历。

中序遍历:首先,创建一个指针p指向二叉树的树根,然后将p压入栈中并让p指向其左孩子,直到p指向的为NULL。然后令栈中存的结点指针出栈,输出其指向的data,并让其指向其右孩子,若不为空,则输出数据。直到栈为空,结束。此时就完成了二叉树的中序遍历。

代码

#include "stdio.h"
#include "stdlib.h"
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef char SElemType;

typedef struct TreeNode{
    SElemType data;
    struct TreeNode *lchild,*rchild;
}TreeNode,*BiTree;

//创建树
int CreateTree(BiTree *root){ 
    char ch;
    scanf("%c",&ch);
    getchar();
    if(ch=='#'){
        *root=NULL;
    }else{
        *root=(TreeNode *)malloc(sizeof(TreeNode));
        if(!*root)
            exit(-1);
        (*root)->data=ch;
        CreateTree(&((*root)->lchild));
        CreateTree(&((*root)->rchild));
    }
    return 0;
}

//栈的结构
typedef struct{
    BiTree *base;
    BiTree *top;
    int stacksize;
}SqStack;

//创建栈
int InitStack(SqStack *s){
    s->base=(BiTree *)malloc(STACK_INIT_SIZE*sizeof(BiTree));
    if(!s->base) exit(0); 
    s->top=s->base;
    s->stacksize=STACK_INIT_SIZE;
    return 1;
}

//获取栈顶元素
int GetTop(SqStack s,BiTree *e){
    if(s.top==s.base) return 0;
    *e=*(s.top-1);
    return 1;
}

//入栈
int Push(SqStack *s,BiTree e){
    if(s->top-s->base>=s->stacksize){
        s->base=(BiTree *)realloc(s->base,(s->stacksize+STACK_INIT_SIZE)*sizeof(BiTree));
        if(!s->base) exit(0);
        s->top=s->base+s->stacksize;
        s->stacksize+=STACKINCREMENT;
    }
    *(s->top++)=e;    //若栈不为空,用e返回其值
    return 1;
}

//出栈
int Pop(SqStack *s,BiTree *e){
    if(s->top==s->base)
        return 0;
    *e=*--(s->top);
    return 1;
}

//判空
int StackEmpty(SqStack *s){
    if(s->base==s->top){
        return 1;
    }else{
        return 0;
    }
}

//先序遍历
void preOrder(BiTree tree){    
    SqStack s;
    BiTree e;
    InitStack(&s);
    BiTree p=tree;
    while(p!=NULL || !StackEmpty(&s)){
        while(p!=NULL){
            printf("%c ",p->data);
            Push(&s,p);
            p=p->lchild;
        }
        if(!StackEmpty(&s)){
            Pop(&s,&e);
            p=e;
            p=p->rchild;
        }
    }
}

//中序遍历
void inOrder(BiTree tree){    
    SqStack s;
    BiTree e;
    InitStack(&s);
    BiTree p=tree;
    while(p!=NULL || !StackEmpty(&s)){
        while(p!=NULL){
            Push(&s,p);
            p=p->lchild;
        }
        if(!StackEmpty(&s)){
            Pop(&s,&e);
            p=e;
            printf("%c ",p->data);
            p=p->rchild;
        }
    }
}

int main(){
    BiTree tree;
    CreateTree(&tree);
    printf("先序遍历:");
    preOrder(tree);
    printf("\n中序遍历:");
    inOrder(tree);
    getchar();
    return 0;
}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值