• 二叉树的层次遍历-1


    1.二叉树层次遍历的原理

    算法思想:
      利用队列实现的,因为层次遍历的序列正好符合队列的特性,先进先出,所以用队列这个工具实现二叉树的层次遍历
      但pay attention to 这里我用的是循环队列,因我害怕队列溢出,导致内存泄漏的不规范行

    2.代码如下

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #define MaxSize 50
    using namespace std;
    typedef char ElemType;
    //树结点定义
    typedef struct node{
        ElemType data;
        struct node* lchild,*rchild;
    }BiTNode,*BiTree;
    
    //采用循环队列定义
    typedef struct{
        BiTree value[MaxSize];
        int front,rear;
    }Qunue;
    //初始化循环队列
    void InitQunue(Qunue &Q)
    {
        Q.front=Q.rear=0;
    }
    //入队操作
    bool EnQunue(Qunue &Q,BiTree x)
    {
        //入队判断队列是否满了
        if((Q.rear+1)%MaxSize==Q.front)
        {
            printf("循环队列已经满了,无法入队了!
    ");
            return false;
        }
        else{
            Q.value[Q.rear]=x;
            Q.rear=(Q.rear+1)%MaxSize;
            return true;
        }
    }
    //出队操作
    bool DeQunue(Qunue &Q,BiTree &x)
    {
        //出队操作判断队列是否为空
        if(Q.rear==Q.front)
        {
            printf("队列为空,无法出队!
    ");
            return false;
        }
        else{
            x=Q.value[Q.front];
            Q.front=(Q.front+1)%MaxSize;
            return false;
        }
    }
    //判断队列是否为空
    bool EmpytQunue(Qunue Q)
    {
        if(Q.rear==Q.front)
        {
            return true;
        }
        else{
            return false;
        }
    }
    
    //初始化一个空的二叉树
    void InitBiTree(BiTree &tree)
    {
        // tree存储NULL,表示没有二叉树
        tree=NULL;
    }
    //先序递归创建二叉树  #表示空结点
    //eg: 12#### 表示的是根为1,左孩子为2
    void CreateBitree(BiTree &T)
    {
        char ch;
        if((ch=getchar())=='#')
            T=NULL;
        else
        {
            T=(BiTNode*)malloc(sizeof(BiTNode));
            T->data=ch;
            CreateBitree(T->lchild);
            CreateBitree(T->rchild);
        }
    }
    
    //层次遍历
    bool LevelOrder(BiTree &tree)
    {
        Qunue Q;  初始化一个循环队列
        InitQunue(Q);
        BiTree p=tree,q,r;   //保护
        if (p)
        {
            EnQunue(Q,p);  //先把根节点入队,为了构造循环结束的条件,队列为空
        }
        else{
            cout<<"二叉树为空,无法进行层次遍历!"<<endl;
            return false;
        };
        while(!EmpytQunue(Q))
        {
            if(p->lchild)   //左孩子结点存在,入队
            {
                EnQunue(Q,p->lchild);
            }
            if (p->rchild)  //右孩子节点存在入队
            {
                EnQunue(Q,p->rchild);   //当处理完下一行时,上一行的左结点出队包括根节点(其实也可一全进入队列里最后在统一出队,都可以)
                DeQunue(Q,p);  //出队列
                printf("%c",p->data);  //输出结点值
                if(p->lchild==NULL)  //if-else 为了,让p指向下一行的左结点或者右结点(因为右结点可能不存在)
                    p=p->rchild;
                else
                    p=p->lchild;
            }
            if(p->lchild==NULL&&p->rchild==NULL)   //当p的左右都为空时,结束层次遍历
                while (!EmpytQunue(Q))
                {
                    DeQunue(Q,p);
                    printf("%c",p->data);   //输出队列中保存的所有结点数据
                }
        }
        return true;
    }
    
    int main()
    {
        BiTree tree;    //创建一个二叉树结点指针
        InitBiTree(tree); //初始化一个空二叉树
        CreateBitree(tree);  //先序递归创建一个二叉树
      
        LevelOrder(tree);  //层次遍历结果序列
    
    
        return 0;
    }
    第一种实现
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #define MaxSize 50
    using namespace std;
    typedef char ElemType;
    //树结点定义
    typedef struct node{
        ElemType data;
        struct node* lchild,*rchild;
    }BiTNode,*BiTree;
    
    //采用循环队列定义
    typedef struct{
        BiTree value[MaxSize];
        int front,rear;
    }Qunue;
    //初始化循环队列
    void InitQunue(Qunue &Q)
    {
        Q.front=Q.rear=0;
    }
    //入队操作
    bool EnQunue(Qunue &Q,BiTree x)
    {
        //入队判断队列是否满了
        if((Q.rear+1)%MaxSize==Q.front)
        {
            printf("循环队列已经满了,无法入队了!
    ");
            return false;
        }
        else{
            Q.value[Q.rear]=x;
            Q.rear=(Q.rear+1)%MaxSize;
            return true;
        }
    }
    //出队操作
    bool DeQunue(Qunue &Q,BiTree &x)
    {
        //出队操作判断队列是否为空
        if(Q.rear==Q.front)
        {
            printf("队列为空,无法出队!
    ");
            return false;
        }
        else{
            x=Q.value[Q.front];
            Q.front=(Q.front+1)%MaxSize;
            return false;
        }
    }
    //判断队列是否为空
    bool EmpytQunue(Qunue Q)
    {
        if(Q.rear==Q.front)
        {
            return true;
        }
        else{
            return false;
        }
    }
    
    //初始化一个空的二叉树
    void InitBiTree(BiTree &tree)
    {
        // tree存储NULL,表示没有二叉树
        tree=NULL;
    }
    //先序递归创建二叉树  #表示空结点
    void CreateBitree(BiTree &T)
    {
        char ch;
        if((ch=getchar())=='#')
            T=NULL;
        else
        {
            T=(BiTNode*)malloc(sizeof(BiTNode));
            T->data=ch;
            CreateBitree(T->lchild);
            CreateBitree(T->rchild);
        }
    }
    
    //层次遍历
    bool LevelOrder(BiTree &tree)
    {
        Qunue Q;
        InitQunue(Q);
        BiTree p=tree,q,r;   //保护
        if (p)
        {
            EnQunue(Q,p);  //先把跟入队,为了判断
        }
        else{
            cout<<"二叉树为空,无法进行层次遍历!"<<endl;
            return false;
        };
        while(!EmpytQunue(Q))
        {
            if(p->lchild)
            {
                q=p->lchild;
                EnQunue(Q,p->lchild);
            }
            if (p->rchild)
            {
                EnQunue(Q,p->rchild);
                DeQunue(Q,p);  //出队列  第二种逻辑控制,一次出对两个,正好把p赋值成左结点了
                printf("%c",p->data);
                DeQunue(Q,p);
                printf("%c",p->data);
    //            if(p->lchild==NULL)
    //                p=p->rchild;
    //            else
    //                p=p->lchild;
            }
            if(p->lchild==NULL&&p->rchild==NULL)   //当p的左右都为空时,结束层次遍历
                while (!EmpytQunue(Q))
                {
                    DeQunue(Q,p);
                    printf("%c",p->data);
                }
        }
        return true;
    }
    
    int main()
    {
        BiTree tree;
        InitBiTree(tree);
        CreateBitree(tree);
        LevelOrder(tree);
    
    
        return 0;
    }
    第二种实现
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #define MaxSize 50
    using namespace std;
    typedef char ElemType;
    //树结点定义
    typedef struct node{
        ElemType data;
        struct node* lchild,*rchild;
    }BiTNode,*BiTree;
    
    //采用循环队列定义
    typedef struct{
        BiTree value[MaxSize];
        int front,rear;
    }Qunue;
    //初始化循环队列
    void InitQunue(Qunue &Q)
    {
        Q.front=Q.rear=0;
    }
    //入队操作
    bool EnQunue(Qunue &Q,BiTree x)
    {
        //入队判断队列是否满了
        if((Q.rear+1)%MaxSize==Q.front)
        {
            printf("循环队列已经满了,无法入队了!
    ");
            return false;
        }
        else{
            Q.value[Q.rear]=x;
            Q.rear=(Q.rear+1)%MaxSize;
            return true;
        }
    }
    //出队操作
    bool DeQunue(Qunue &Q,BiTree &x)
    {
        //出队操作判断队列是否为空
        if(Q.rear==Q.front)
        {
            printf("队列为空,无法出队!
    ");
            return false;
        }
        else{
            x=Q.value[Q.front];
            Q.front=(Q.front+1)%MaxSize;
            return false;
        }
    }
    //判断队列是否为空
    bool EmpytQunue(Qunue Q)
    {
        if(Q.rear==Q.front)
        {
            return true;
        }
        else{
            return false;
        }
    }
    
    //初始化一个空的二叉树
    void InitBiTree(BiTree &tree)
    {
        // tree存储NULL,表示没有二叉树
        tree=NULL;
    }
    //先序递归创建二叉树  #表示空结点
    void CreateBitree(BiTree &T)
    {
        char ch;
        if((ch=getchar())=='#')
            T=NULL;
        else
        {
            T=(BiTNode*)malloc(sizeof(BiTNode));
            T->data=ch;
            CreateBitree(T->lchild);
            CreateBitree(T->rchild);
        }
    }
    
    //层次遍历
    bool LevelOrder(BiTree &tree)
    {
        Qunue Q;
        InitQunue(Q);
        BiTree p=tree;   //保护
        if (p)
        {
            EnQunue(Q,p);  //先把跟入队,为了判断
        }
        else{
            cout<<"二叉树为空,无法进行层次遍历!"<<endl;
            return false;
        };
        while(!EmpytQunue(Q))
        {
            DeQunue(Q,p);
            printf("%c",p->data);  //这里放置访问结点的各种操作  这里用的只是输出
            if(p->lchild)
            {
                EnQunue(Q,p->lchild);
            }
            if (p->rchild)
            {
                EnQunue(Q,p->rchild);
            }
        }
        return true;
    }
    
    int main()
    {
        BiTree tree;
        InitBiTree(tree);
        CreateBitree(tree);
        LevelOrder(tree);
    
    
        return 0;
    }
    第三种实现

    本质都是一样的,只不过改了改逻辑.

    3.要变通,printf语句那里可以替换成你想要的任何语句

    4.结果测试  

  • 相关阅读:
    浅谈Android内存管理
    adb 常用命令
    ElasticSearch+Logstash+Filebeat+Kibana集群日志管理分析平台搭建
    分布式版本控制系统GIT的使用
    KVM虚拟化原理与基础应用示例
    Nginx反代Mogilefs分布式储存示例
    Redis持久化存储与复制功能简述
    Redis服务搭建与基础功能示例
    常用的NoSQL数据库类型简述
    XtraBackup的备份原理与应用示例
  • 原文地址:https://www.cnblogs.com/nanfengnan/p/14544994.html
Copyright © 2020-2023  润新知