二叉树的层序遍历 (层次遍历 广度优先遍历)(14.7版)

文章详细介绍了C++中二叉树的结构以及四种遍历方法(前序、中序、后序和层序),并使用辅助队列(LinkQueue)进行操作,展示了如何在`function.h`和`main.cpp`中实现这些功能。
摘要由CSDN通过智能技术生成

function.h文件:

//
// Created by legion on 2024/3/5.
//

#ifndef INC_14_4_TREE_FUNCTION_H
#define INC_14_4_TREE_FUNCTION_H
#include <stdio.h>
#include <stdlib.h>

typedef char BiElemType;
typedef struct BiTNode{
    BiElemType c;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}BiTNode,*BiTree;

//tag结构体是辅助队列使用的 队列是由链表实现的
typedef struct tag{
    BiTree p;//树的某一个结点的地址值
    struct tag *pnext;
}tag_t,*ptag_t;//这个链表结构体类型tag_t 为什么和结构体名不一致

//辅助队列 的结构体
typedef BiTree ElemType;
typedef struct LinkNode{
    ElemType data;//
    struct LinkNode *next;
}LinkNode;
typedef struct{//队列结构体
    LinkNode *front,*rear;//链表头 链表尾 可以称为队头 队尾
}LinkQueue;//先进先出


void InitQueue(LinkQueue &Q);
//入队

bool IsEmpty(LinkQueue Q);

void EnQueue(LinkQueue &Q,ElemType x);//不修改故不引用
//出队
bool DeQueue(LinkQueue &Q,ElemType &x);//出队后有可能发生real指向头指针 Q有可能发生改变 所以引用

#endif //INC_14_4_TREE_FUNCTION_H

queue.cpp:

//
// Created by legion on 2024/3/5.
//

#ifndef INC_14_4_TREE_FUNCTION_H
#define INC_14_4_TREE_FUNCTION_H
#include <stdio.h>
#include <stdlib.h>

typedef char BiElemType;
typedef struct BiTNode{
    BiElemType c;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}BiTNode,*BiTree;

//tag结构体是辅助队列使用的 队列是由链表实现的
typedef struct tag{
    BiTree p;//树的某一个结点的地址值
    struct tag *pnext;
}tag_t,*ptag_t;//这个链表结构体类型tag_t 为什么和结构体名不一致

//辅助队列 的结构体
typedef BiTree ElemType;
typedef struct LinkNode{
    ElemType data;//
    struct LinkNode *next;
}LinkNode;
typedef struct{//队列结构体
    LinkNode *front,*rear;//链表头 链表尾 可以称为队头 队尾
}LinkQueue;//先进先出


void InitQueue(LinkQueue &Q);
//入队

bool IsEmpty(LinkQueue Q);

void EnQueue(LinkQueue &Q,ElemType x);//不修改故不引用
//出队
bool DeQueue(LinkQueue &Q,ElemType &x);//出队后有可能发生real指向头指针 Q有可能发生改变 所以引用

#endif //INC_14_4_TREE_FUNCTION_H

main.cpp

#include "function.h"
//前序遍历函数,也叫先序遍历,也是深度优先遍历
void PreOrder(BiTree p)//只是遍历 即只是读,不会改变树根
{//这个p的类型是 树的结构体 不是之前的p指针
    if(p!=NULL)
    {
        printf("%c", p->c);
        PreOrder(p->lchild);//函数嵌套 打印左子树
        PreOrder(p->rchild);//函数嵌套 打印右子树
    }
}
//中序遍历
void InOrder(BiTree p)//只是遍历 即只是读,不会改变树根
{//这个p的类型是 树的结构体 不是之前的p指针
    if(p!=NULL)
    {
        InOrder(p->lchild);//函数嵌套 打印左子树
        printf("%c", p->c);
        InOrder(p->rchild);//函数嵌套 打印右子树
    }
}
//后续遍历
void PostOrder(BiTree p)//只是遍历 即只是读,不会改变树根
{//这个p的类型是 树的结构体 不是之前的p指针
    if(p!=NULL)
    {
        PostOrder(p->lchild);//函数嵌套 打印左子树
        PostOrder(p->rchild);//函数嵌套 打印右子树
        printf("%c", p->c);
    }
}

//层序遍历
//层次遍历 层序遍历 广度优先遍历
void LevelOrder(BiTree T)//树的结构体指针 有左孩子和有孩子
{
    LinkQueue Q;//定义一个队列Q
    InitQueue(Q);//初始化队列Q 队头等于队尾  next指针指向NULL
    BiTree p;//存储出队的结点 p为一个树的结构体指针
    EnQueue(Q,T);//把根入队
    while(!IsEmpty(Q))//队列不为空才进入到循环当中
    {
        DeQueue(Q,p);
        putchar(p->c);//等价于printf("%c",c);
        if(p->lchild)
        {
            EnQueue(Q,p->lchild);//左孩子不为空 入队左孩子
        }
        if(p->rchild)
        {
            EnQueue(Q,p->rchild);
        }
    }


}

int main() {
    BiTree pnew;//用来指向新申请的树结点 结构体指针类型
    BiTree tree=NULL;//tree是指向树根的,代表树
    char c;
    //定义队列 phead是队列头ptail是队列尾 listpnew指向新结点 pcur是指向当前父结点
    ptag_t phead=NULL,ptail=NULL,listpnew=NULL,pcur;
    //输入abcdefghij
    while(scanf("%c",&c))
    {
        if(c=='\n')
        {
            break;//读取换行结束
        }
        //calloc申请的空间大小是两个参数直接相乘,并对空间进行初始化,赋值为0
        pnew= (BiTree)calloc(1,sizeof(BiTNode));
        pnew->c=c;//数据放进去
        listpnew= (ptag_t)calloc(1,sizeof(tag_t));//给队列结点申请空间
        listpnew->p=pnew;
        if(NULL==tree)//如果树为空 放进去即为树根
        {
            tree=pnew;//树的根
            phead=listpnew;//队列头
            ptail=listpnew;//队列尾
            pcur=listpnew;
            continue;
        } else{
            ptail->pnext=listpnew;//新结点放入链表 通过尾插法
            ptail=listpnew;//ptail指向队列尾部
        }//pcur始终指向要插入的结点的位置
        if(NULL==pcur->p->lchild)
        {
            pcur->p->lchild=pnew;//把新结点放到要插入结点的左边
        } else if(NULL==pcur->p->rchild)
        {
            pcur->p->rchild=pnew;//把新结点放到要插入结点的右边
            pcur=pcur->pnext;//左右都放了结点后,pcur指向队列下一个
        }
    }

 //14.5二叉树的前序中序后续遍历
    printf("------------PreOrder------------\n");
    PreOrder(tree);
    printf("\n------------InOrder------------\n");
    InOrder(tree);
    printf("\n------------PostOrder------------\n");
    PostOrder(tree);
    printf("\n------------LevelOrder------------\n");
    LevelOrder(tree);
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

陆小果不会写代码

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

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

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

打赏作者

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

抵扣说明:

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

余额充值