数据结构-树-二叉树的层序遍历

数据结构-树-二叉树的层序遍历

二叉树的层序遍历需要结合指针队列来实现输出,思路比较简单,机构比较复杂。

接着“数据结构-树-二叉树的遍历”的树做例子

1.将所有用到的结构体定义出来(这里包含了树的结构和队列的结构)

// 二叉树的基本结构
typedef struct BinNode {
    ElemType data; // 数据域
    struct BinNode *lchild, *rchild; // 左右孩子节点
}BinNode, *BinTree;

// 定义队列的节点(存储类型)
typedef struct LinkNode {
    BinTree data; // 队列存放指向二叉树的节点指针
    struct LinkNode * next; // 指向队列的下一个元素
}LinkNode;

// 保存队列指针的结构体
typedef struct {
    LinkNode * front, * rear; // 队列的对头和队尾指针
}LinkQueue;

2.队的基本方法实现

void InitQueue(LinkQueue *); // 初始化队列
int IsEmpty(LinkQueue *); // 判断是否为空
int EnQueue(LinkQueue *, BinTree); // 入队
BinTree DeQueue(LinkQueue * queue); // 出队
void ClearQueue(LinkQueue *); // 销毁队列

// 二叉树的队列的初始化
void InitQueue(LinkQueue *  queue) {
    queue->front = NULL;
    queue->rear = NULL;
}

// 判断队列是否为空
int IsEmpty(LinkQueue * queue) {
    if (queue->front == NULL || queue->rear == NULL) {
        return 1;
    }
    return 0;
}

// 二叉树的节点入队
int EnQueue(LinkQueue * queue, BinTree treeNode) {

    // 判断节点是否符合条件
    if (treeNode == NULL) { // 二叉树的指针为空,非法插入
        printf("所给树的节点为空,插入失败!\n");
        return 0;
    }

    // 将树的节点封装到队列节点内
    LinkNode * linkNode = (LinkNode *)malloc(sizeof(LinkNode));
    linkNode->data = treeNode;
    linkNode->next = NULL;

    // 判断队列是否为空
    if (IsEmpty(queue)) {
        // 队为空
        queue->front = linkNode;
        queue->rear = linkNode;
        return 1;
    } else {
        // 从队尾插入
        queue->rear->next = linkNode;
        queue->rear = linkNode;
        return 1;
    }
}

// 二叉树节点的出队
BinTree DeQueue(LinkQueue * queue) {
    // 判断队列是否为空,为空出队失败
    if (IsEmpty(queue)) {
        printf("队列为空,出队失败!\n");
        return NULL;
    }

    BinTree treeNode;
    // 将保存结果的指针(第二个参数)指向队头指针
    treeNode = queue->front->data;
    // 对头指针向后移动
    queue->front = queue->front->next;
    return treeNode;
}

// 销毁队列
void ClearQueue(LinkQueue * queue) {
    LinkNode * temp = queue->front;
    while (temp != queue->rear) {
        queue->front = queue->front->next;
        free(temp);
        temp = queue->front;
    }
    queue->front = queue->rear = NULL;
    free(temp);
}

3.层序遍历的方法实现(***)

// 层序遍历
void LevelOrder(BinTree tree) {
    // 创建队列
    LinkQueue queue;
    // 队列初始化
    InitQueue(&queue);
    // 根节点入队
    EnQueue(&queue, tree); // tree是否为空在EnQueue方法内已经实现判断,此处无需在此判断
    // 创建一个临时的BinTree节点保存出队的结果
    BinTree temp;
    printf("层序遍历:");
    while (!IsEmpty(&queue)) {
        temp = DeQueue(&queue); // 出队
        printf("%5c", temp->data); // 输出
        // 将该节点的子节点依次顺序加入队列
        if (temp->lchild != NULL) {
            EnQueue(&queue, temp->lchild);
        }
        if (temp->rchild != NULL) {
            EnQueue(&queue, temp->rchild);
        }
    }
    printf("\n");
}

有错误欢迎指正,没有太严谨的测试。

层序遍历:    A    B    C    D    E
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值