二叉树链式存储的前中后递归和非递归遍历、层序遍历实现

二叉树链式存储的前中后递归和非递归遍历、层序遍历实现

1. 二叉树的链式存储结构
#define ElementType char
typedef struct BTNode{
    ElementType data;
    struct BTNode *left,*right;
}BTNode,*BinTree;
2. 二叉树的前序、中序、后序递归遍历

时间复杂度和空间复杂度都为O(n)

前序
  • 如果二叉树空,则空操作;
  • 如果不空,
    • 先访问根结点
    • 然后前序遍历左子树
    • 再前序遍历右子树
void PreOderTraverse(BinTree T){
    if(!T) return;
    else {
        printf("%c\t",T->data);
        PreOderTraverse(T->left);
        PreOderTraverse(T->right);
    }
}
中序
  • 如果二叉树空,则空操作;
  • 如果不空,
    • 中序遍历左子树
    • 访问根结点
    • 中序遍历右子树
void PreOderTraverse(BinTree T){
    if(!T) return;
    else {
        printf("%c\t",T->data);
        PreOderTraverse(T->left);
        PreOderTraverse(T->right);
    }
}
后序
  • 如果二叉树空,则空操作;
  • 如果不空,
    • 后序遍历左子树
    • 后序遍历右子树
    • 访问根结点
void PreOderTraverse(BinTree T){
    if(!T) return;
    else {
        printf("%c\t",T->data);
        PreOderTraverse(T->left);
        PreOderTraverse(T->right);
    }
}

输入的二叉树如下:

运行测试
int main(void)
{   
    //创建二叉树
    BinTree A = (BinTree)malloc(sizeof(struct BTNode));
    A->data = 'A';

    BinTree B = (BinTree)malloc(sizeof(struct BTNode));
    B->data = 'B';

    BinTree C = (BinTree)malloc(sizeof(struct BTNode));
    C->data = 'C';

    BinTree D = (BinTree)malloc(sizeof(struct BTNode));
    D->data = 'D';

    BinTree E = (BinTree)malloc(sizeof(struct BTNode));
    E->data = 'E';

    BinTree F = (BinTree)malloc(sizeof(struct BTNode));
    F->data = 'F';
    
    A->left = B;A->right = C;
    B->left = D;B->right = E;
    C->left = F;C->right = NULL;
    D->left = NULL;D->right =NULL;
    E->left = NULL;E->right =NULL;
    F->left = NULL;F->right =NULL;
    

    //前序遍历
    printf("先序遍历:");
    PreOderTraverse(A);
    printf("\n");
    //中序遍历
    printf("中序遍历:");
    InOderTraverse(A);
    printf("\n");
    //后序遍历
    printf("后序遍历:");
    PostOrderTraverse(A);
    printf("\n");
    //释放内存
    free(A);
    free(B);
    free(C);
    free(D);
    free(E);
    free(F);
    
    return 0;
}

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

3. 二叉树的非递归遍历

中序非递归遍历,利用栈的链式存储来实现中序非递归遍历

存放二叉树结点的栈的链式存储结构、创建空栈、判空、出栈、入栈
/*栈的结点结构*/
typedef struct SNode{
    BinTree data;
    struct SNode *next;
}*Stack;

/*创建空栈*/
Stack CreateStack(){
    //创造头结点S,S不定义任何元素
    Stack S = (Stack)malloc(sizeof(struct SNode));
    S->next = NULL;
    return S;
}

/*判断栈空不空*/
int IsEmpty(Stack S){
    return (S->next == NULL);
}

/*入栈*/
void Push(Stack S,BinTree T){
        Stack newone = (Stack)malloc(sizeof(struct SNode));
        newone->data = T;
        newone->next = S->next;
        S->next = newone;
}

/*出栈*/
BinTree Pop(Stack S){
    if (!S)
    {   
        return NULL;
    }else{
        Stack tmp;BinTree T;

        tmp = S->next;//获取要删除的结点
        S->next = tmp->next;//更新栈顶的下一个结点地址
        T = tmp->data;//获取被弹出的栈元素的值

        free(tmp);//释放弹出的栈顶结点内存
        return T;
    }
}
先序非递归遍历二叉树
void InOrderTraverse(BinTree T){
    Stack S = CreateStack();//创建有头结点的空栈的指针
    BinTree p = T;//临时树结点
    BinTree q;
    while (p || !IsEmpty(S)) //树不空或者栈空 
    {
        if (p) 
        {
            Push(S,p);//将根结点的指针放入栈中
            p = p->left;//查看左子树,遍历左子树
        }else{
            //如果左子树遍历完,则从栈弹出根结点的值,开始遍历右子树
            q = Pop(S); 
            printf("%c\t",q->data);
            p = q->right;
        }
    }
}
运行测试

//创建二叉树同上
//测试中序非递归遍历二叉树
    printf("中序非递归遍历:\n");
    InOrderTraverse(A);

输出结果如下:
在这里插入图片描述

4. 层序遍历

层次遍历,利用队列的顺序存储结构实现

存放二叉树结点的队列的顺序存储结构、创建空队列、判空、入队、出队
/*定义队列的顺序存储结构*/
typedef struct QNode
{
    BinTree DataArray[MaxSize];//存放二叉树结点地址的数组
    int front,rear;//队头和队尾下标
    /*当front = rear时,链表为空*/
}*Queue;

/*创建空队列*/
Queue CreateQ(){
    Queue Q = (Queue)malloc(sizeof(struct QNode));
    Q->front = Q->rear = -1;
    return Q;
}

/*入队,尾加*/
void AddQ(Queue Q,BinTree bt){
    if ((Q->rear+1)%MaxSize == Q->front) return; /* 判断队列是否满 */
    Q->rear = (Q->rear+1)%MaxSize;
    Q->DataArray[Q->rear] = bt;  
}

/* 出队,头删 */
BinTree DeQ(Queue Q){
    if (Q->front == Q->rear) //判断队列是不是空
    {   
        printf("\nit is null.\n");
        return NULL;
    }else{
        Q->front = (Q->front+1)%MaxSize;
        BinTree bt = Q->DataArray[Q->front];
        return bt;
    }
}

/* 判断队列是否为空 */
int IsEmpty(Queue Q){
    return (Q->front == Q->rear);
}
层级遍历二叉树
void LevelTraversal(BinTree T){
    if(!T) return; //空二叉树
    //创建空队列
    Queue Q = CreateQ();
    BinTree p;
    //入队
    AddQ(Q,T); //根结点进入队列
    while (!IsEmpty(Q)) //队不为空则循环
    {
        //出队
        p = DeQ(Q);
        printf("%c\t",p->data);
        if(p->left) AddQ(Q,p->left);
        if(p->right) AddQ(Q,p->right);
    }
}
运行测试
//测试层次非递归遍历二叉树
    printf("层次非递归遍历:\n");
    LevelTraversal(A);

结果如图
在这里插入图片描述

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值