二叉树层序遍历

层次遍历:
  使用双向循环链表,尾部入队,头部出队。同时使用头结点方便出队和入队操作

函数声明:

void CreatTree(TreeNode **tree,char *data,int *index);      //创建二叉树
QueueNode *InitQueue();                                     //初始化队列
void enQueue(TreeNode *tree,QueueNode * queue);             //入队
boolean isEmpty(QueueNode *queue);                          //判断队列是否为空
QueueNode *deQueue(QueueNode *queue);                       //出队
void levelTraverse(QueueNode *queue,TreeNode *tree);        //层序遍历

定义结构体:

#include <stdio.h>
#include <windows.h>

//树
typedef struct TreeNode
{
    char val;                   //保存树的内容
    struct TreeNode *lchild;    //指向树的左孩子
    struct TreeNode *rchild;    //指向树的右孩子
}TreeNode;

//队列
typedef struct QueueNode
{
    TreeNode *data;              //存储二叉树结点
    struct QueueNode *next;      //指向下一结点
    struct QueueNode *pre;       //指向前一结点
}QueueNode;

层序遍历:

void levelTraverse(QueueNode *queue,TreeNode *tree)
{   //根结点入队
    enQueue(tree,queue);
    while(!isEmpty(queue))
    {   //队列非空时出队
        QueueNode *node = deQueue(queue);
        //访问结点
          printf("%c\t",node->data->val);
          //判断二叉树是个否有左孩子
        if(node->data->lchild)
        {   //左孩子入队
            enQueue(node->data->lchild,queue);
        }
        //判断二叉树是否有右孩子
        if(node->data->rchild)
        {   //右孩子入队
            enQueue(node->data->rchild,queue);
        }
    }
    printf("\n");
}

初始化队列:

//初始化队列
QueueNode *InitQueue()
{
    QueueNode * queue = (QueueNode *)malloc(sizeof(QueueNode));
    queue->data = NULL;    //初始化队列数据指向为空
    queue->pre = queue;    //初始化队列头结点指向
    queue->next = queue;   //初始化队列头结点指向
    return queue;
}

入队操作:

//入队操作
void enQueue(TreeNode *tree,QueueNode *queue)
{
    QueueNode *node = (QueueNode *)malloc(sizeof(QueueNode));
    if(node == NULL)
        return ;
    
    node->data = tree;          //存储传入元素的地址
    node->pre = queue->pre;     //新结点的pre指向队列尾结点(双向循环链表 queue->pre 为尾结点)
    node->next = queue;         //新结点的next指向队头
    queue->pre->next = node;    //队列尾结点指向新结点
    queue->pre = node;          //队头的pre指向新结点(此时新结点更新为尾结点)
}

出队操作:

//出队操作(头部出队)
QueueNode *deQueue(QueueNode *queue)
{
    if(isEmpty(queue))
    {
        return NULL;
    }
    else
    {   
        QueueNode *node = queue->next;      //辅助结点,指向首元素
        node->next->pre = queue;            //出队结点的下一结点pre指针指向头结点
        queue->next = node->next;           //头结点的next指针指向删除结点的next指向的结点
        return node;                        
    }
}

判断队列是否为空:

boolean isEmpty(QueueNode *queue)
{
    if(queue->next == queue)
        return TRUE;
    return FALSE;
}

程序:

#include "inorder.h"

void main()
{
    TreeNode *tree;
    QueueNode *queue = InitQueue();      //初始化队列

    int index = 0;
    char *data = "ABD##E##CF##G##";
    CreatTree(&tree,data,&index);       //创建二叉树
    levelTraverse(queue,tree);          //层序遍历

    system("pause");
    return ;
}

void CreatTree(TreeNode **T,char *data,int *index)
{
    char ch;
    ch = data[*index];
    *index += 1;
    if(ch == '#')
    {
        //此时为空结点
        *T = NULL;
    }
    else
    {
        //非空结点
        *T = (TreeNode *)malloc(sizeof(TreeNode));
        (*T)->val = ch;
        //创建左子树
        CreatTree(&((*T)->lchild),data,index);
        //创建右子树
        CreatTree(&((*T)->rchild),data,index);
    }
}


//初始化队列
QueueNode *InitQueue()
{
    QueueNode * queue = (QueueNode *)malloc(sizeof(QueueNode));
    queue->data = NULL;    //初始化队列数据指向为空
    queue->pre = queue;    //初始化队列头结点指向
    queue->next = queue;   //初始化队列头结点指向
    return queue;
}
//入队操作
void enQueue(TreeNode *tree,QueueNode *queue)
{
    QueueNode *node = (QueueNode *)malloc(sizeof(QueueNode));
    if(node == NULL)
        return ;
    
    node->data = tree;          //存储传入元素的地址
    node->pre = queue->pre;     //新结点的pre指向队列尾结点(双向循环链表 queue->pre 为尾结点)
    node->next = queue;         //新结点的next指向队头
    queue->pre->next = node;    //队列尾结点指向新结点
    queue->pre = node;          //队头的pre指向新结点(此时新结点更新为尾结点)
}
//出队操作(头部出队)
QueueNode *deQueue(QueueNode *queue)
{
    if(isEmpty(queue))
    {
        return NULL;
    }
    else
    {   
        QueueNode *node = queue->next;      //辅助结点,指向首元素
        node->next->pre = queue;            //出队结点的下一结点pre指针指向头结点
        queue->next = node->next;           //头结点的next指针指向删除结点的next指向的结点
        return node;                        
    }
}

boolean isEmpty(QueueNode *queue)
{
    if(queue->next == queue)
        return TRUE;
    return FALSE;
}
void levelTraverse(QueueNode *queue,TreeNode *tree)
{   //根结点入队
    enQueue(tree,queue);
    while(!isEmpty(queue))
    {   //队列非空时出队
        QueueNode *node = deQueue(queue);
          printf("%c\t",node->data->val);
          //判断二叉树是个否有左孩子
        if(node->data->lchild)
        {   //左孩子入队
            enQueue(node->data->lchild,queue);
        }
        //判断二叉树是否有右孩子
        if(node->data->rchild)
        {   //右孩子入队
            enQueue(node->data->rchild,queue);
        }
    }
    printf("\n");
}

创建的二叉树图示:

在这里插入图片描述

测试结果:

在这里插入图片描述

图解分析:

程序使用双向循环链表,图解时为快速画图简单图示
在这里插入图片描述
声明:此文章为学习笔记,如有侵权请联系删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_Byte_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值