二叉树的三种遍历(C语言版和C++版)

二叉树的递归遍历

我想这个对大家应该不难,所以大家就直接看我的代码吧,我主要还是给大家讲讲非递归代码的实现。(代码在最后)大家只要把代码敲一遍,不管是递归还是非递归应该都能理解。

二叉树的非递归遍历

中序遍历:1,沿着根结点,向左依次入栈,直到左孩子为空
2,栈顶元素出栈并访问,若右孩子为空,继续执行。
3,若右孩子不为空,则将右孩子转执行1。

先序遍历:与中序遍历是一样的,只是把访问操作放到入栈之前

后序遍历:(这个是最特殊的了):
1,沿根的左孩子依次入栈,直到左孩子为空。
2,读栈顶元素,如果栈顶元素是刚刚被访问过的或者右孩子为空,就栈顶元素出栈并访问
3,如果栈顶元素没被访问(gettop(s,p)!= r)且右孩子不为空,将右孩子转执行1。

下面是代码和执行的结果

#include<stdio.h>
#include<stdlib.h>

#define null 0
#define Elemtype char
#define elemtype BiTree
#define maxsize 30
#define false 0
#define true 1
#define bool int
typedef struct BiNode{
    Elemtype data;
    struct BiNode *lchild,*rchild;
}BiNode,*BiTree;

typedef struct {
    elemtype data[maxsize];
    int top;
}sqstack;
//初始化栈
void initStack(sqstack *s){
    s->top = -1;
}
//判断栈空 如果stack是空的 则返回true 否则返回 false
bool empty_stack(sqstack s){
    if(s.top == -1){
        return true;
    }else{
        return false;
    }
}
//入栈
void Push(sqstack *s,BiTree p){
        if(s->top == maxsize-1){
        printf("this stack is full");
    }
    else{
        s->data[++(s->top)]= p;
    }
}
//出栈
void Pop(sqstack *s,BiTree *p){
    if(s->top == -1){
        printf("this stack is null!");
    }else{
        *p = s->data[(s->top)--];
    }
}
//获取栈顶元素
void getTop(sqstack s,BiTree *p){
    *p = s.data[s.top];
}

void InitBiTree(BiTree *T){
    Elemtype ch;
    scanf("%c",&ch);

    if(ch == '#'){                       //这一点很重要,字符比较要加单引号
        (*T) = null;
    }else{
        (*T) = (BiNode*)malloc(sizeof(BiNode));
//        if(!*T){
//            printf("defeat to allocation memory");
//        }
        (*T)->data = ch;
        InitBiTree(&((*T)->lchild));
        InitBiTree(&((*T)->rchild));
    }
}

//定义visit函数
void visit (BiTree T){
    printf("%c",T->data);
}


//二叉树的遍历 (递归遍历)

    //先序遍历(递归方法)
void PreOrder(BiTree T){
    if(T!=null){
        visit(T);
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    }
}
    // 中序遍历(递归方法)
void InOrder(BiTree T){
    if(T!=null){
        InOrder(T->lchild);
        visit(T);
        InOrder(T->rchild);
    }
}
    //后序遍历(递归方法)
void PostOrder(BiTree T){
    if(T!=null){
        PostOrder(T->lchild);
        PostOrder(T->rchild);
        visit(T);
    }
}




/***********以下是二叉树的非递归算法*****************/

//中序遍历
void InOrder2(BiTree T){
    sqstack s;
    initStack(&s);
    BiTree p=T; //p是遍历指针
    while(p||!empty_stack(s)){
        if(p){
            Push(&s,p);
            p=p->lchild;
        }
        else{
            Pop(&s,&p);
            visit(p);
            p=p->rchild;
        }
    }

}

//先序遍历(非递归算法)
      //与中序的区别就是把visit操作放在了push前面
void PreOrder2(BiTree T){
    sqstack s;
    initStack(&s);
    BiTree p=T; //p是遍历指针
    while(p||!empty_stack(s)){
        if(p){
            visit(p);
            Push(&s,p);
            p=p->lchild;
        }
        else{
            Pop(&s,&p);
            p=p->rchild;
        }
    }

}

//后序遍历(非递归算法)
void PostOrder2(BiTree T){
    sqstack s;
    initStack(&s);
    BiTree p = T;
    BiNode *r = null;   //r指针为辅助指针,用来判断这个节点是从左子树还是右子树返回的
    while(p||!empty_stack(s)){
        if(p){
            Push(&s,p);
            p = p->lchild;
        }
        else{
            getTop(s,&p);
            if(p->rchild && p->rchild!=r){
                p=p->rchild;
                Push(&s,p);
                p = p->lchild;
            }
            else{
                Pop(&s,&p);
                visit(p);
                r=p;
                p=null;
            }
        }//else
    }//while

}


int main(){
    BiTree T;
    InitBiTree(&T);

    //递归遍历
    printf("先序遍历:");
    PreOrder(T);
    printf("\n");
    printf("中序遍历:");
    InOrder(T);
    printf("\n");
    printf("后序遍历:");
    PostOrder(T);
    printf("\n");

    printf("/********一下是非递归算法*********/\n");
    //非递归遍历
    printf("中序遍历:");
    InOrder2(T);
    printf("\n");
    printf("先序遍历:");
    PreOrder2(T);
    printf("\n");
    printf("后序遍历:");
    PostOrder2(T);
    printf("\n");
}

输入:在这里插入图片描述
输出:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

强大的RGG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值