首页 > 其他分享 >14.6二叉树的层序遍历实战

14.6二叉树的层序遍历实战

时间:2023-04-09 16:56:40浏览次数:38  
标签:14.6 BiTree 打印 pnew pcur 遍历 二叉树 层序 NULL

function.h

//
// Created by 93757 on 2023/3/21.
//

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

typedef char BiElemType;
typedef struct BiTNode{
    BiElemType c;   //c就是书籍上的data
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}BiTNode,*BiTree;

//tag结构体是辅助队列使用的
typedef struct tag{
    BiTree p;     //树的某一节点的地址值
    struct tag *pnext;
}tag_t,*ptag_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);

#endif //INC_1_TREE_FUNCTION_H

queue.cpp

//
// Created by 93757 on 2023/4/9.
//

#include "function.h"
//队列的初始化,使用的是带头结点的链表来实现的
void InitQueue(LinkQueue &Q)
{
    Q.front=Q.rear=(LinkNode*) malloc(sizeof (LinkNode));
    Q.front->next=NULL;
}

//入队
void EnQueue(LinkQueue &Q,ElemType x)
{
    LinkNode *pnew=(LinkNode*) malloc(sizeof (LinkNode));
    pnew->data=x;
    pnew->next=NULL;   //要让next为NULL
    Q.rear->next=pnew;   //尾指针的next指向pnew,因为从尾部入队
    Q.rear=pnew;    //rear要只想新的尾部
}

//判断队列是否为空
bool IsEmpty(LinkQueue Q)
{
    return Q.rear==Q.front;
}
//出队
bool DeQueue(LinkQueue &Q,ElemType &x)
{
    if(Q.rear==Q.front)   //队列为空
    {
        return false;
    }
    LinkNode *q=Q.front->next;   //拿到第一个节点,存入q
    x=q->data;    //获取要出队的元素值
    Q.front->next=q->next;   //让一个节点断链
    if(Q.rear==q)    //链表只剩余一个节点时,被删除后,要改变rear
    {
        Q.rear=Q.front;
    }
    free(q);
    return true;
}

main.cpp

#include "function.h"

//前序遍历,也叫先序遍历,也是深度优先遍历
void PreOrder(BiTree p)
{
    if(p!=NULL)
    {
        printf("%c", p->c);
        PreOrder(p->lchild);  //打印左子树
        PreOrder(p->rchild);  //打印右子树
    }
}

//中序遍历
void InOrder(BiTree p)
{
    if(p!=NULL)
    {
        InOrder(p->lchild);  //打印左子树
        printf("%c", p->c);
        InOrder(p->rchild);  //打印右子树
    }
}

//后续遍历
void PostOrder(BiTree p)
{
    if(p!=NULL)
    {
        PostOrder(p->lchild);  //打印左子树
        PostOrder(p->rchild);  //打印右子树
        printf("%c", p->c);
    }
}

//层序遍历,层次遍历,广度优先遍历
void LevelOrder(BiTree T)
{
    LinkQueue Q;
    InitQueue(Q);
    BiTree p;   //存储出队节点
    EnQueue(Q, T);   //把根入队
    while (!IsEmpty(Q))
    {
        DeQueue(Q,p);
        putchar(p->c);  //等价于printf("%c",c);
        if(p->lchild!=NULL)
        {
            EnQueue(Q,p->lchild);  //左孩子不为空,就入队左孩子
        }
        if(p->rchild)
        {
            EnQueue(Q,p->rchild);  //右孩子不为空,就入队右孩子
        }
    }

}


int main() {
    BiTree pnew;//用来指向新申请的树结点
    BiTree tree=NULL;//tree是指向树根的,代表树
    char c;
    ptag_t phead=NULL,ptail=NULL,listpnew=NULL,pcur=NULL;
    //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;//tree指向树的根结点
            phead=listpnew;//第一个结点即是队列头,也是队列尾
            ptail=listpnew;
            pcur=listpnew;//pcur要指向要进入树的父亲元素
        }else{
            //让元素先入队列
            ptail->pnext=listpnew;
            ptail=listpnew;
            //接下来把b结点放入树中
            if(NULL==pcur->p->lchild)
            {
                pcur->p->lchild=pnew;//pcur->p左孩子为空,就放入左孩子
            }else if(NULL==pcur->p->rchild)
            {
                pcur->p->rchild=pnew;//pcur->p右孩子为空,就放入右孩子
                pcur=pcur->pnext;//当前结点左右孩子都有了,pcur就指向下一个
            }
        }
    }
    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;
}

 

标签:14.6,BiTree,打印,pnew,pcur,遍历,二叉树,层序,NULL
From: https://www.cnblogs.com/su-1007/p/17300559.html

相关文章

  • 二叉树前序中序后序遍历实战
    function函数////Createdby93757on2023/3/21.//#ifndefINC_1_TREE_FUNCTION_H#defineINC_1_TREE_FUNCTION_H#include<stdio.h>#include<stdlib.h>typedefcharBiElemType;typedefstructBiTNode{BiElemTypec;//c就是书籍上的datastru......
  • 14.4二叉树层次建树
    创建function函数////Createdby93757on2023/3/21.//#ifndefINC_1_TREE_FUNCTION_H#defineINC_1_TREE_FUNCTION_H#include<stdio.h>#include<stdlib.h>typedefcharBiElemType;typedefstructBiTNode{BiElemTypec;//c就是书籍上的datast......
  • 剑指 Offer 37. 序列化二叉树
    题目链接:剑指Offer37.序列化二叉树取巧做法classCodec{private:TreeNode*root;public://Encodesatreetoasinglestring.stringserialize(TreeNode*root){this->root=root;return"";}//Decodesyourencoded......
  • JZ8 二叉树的下一个结点
    做法一:直接求出中序遍历,并用vector容器存储。/*structTreeLinkNode{intval;structTreeLinkNode*left;structTreeLinkNode*right;structTreeLinkNode*next;TreeLinkNode(intx):val(x),left(NULL),right(NULL),next(NULL){......
  • 617. 合并二叉树
    给你两棵二叉树:root1和root2。想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为null的节点将直接作为新二叉树......
  • 106. 从中序与后序遍历序列构造二叉树 105. 从前序与中序遍历序列构造二叉树
    给定两个整数数组inorder和postorder,其中inorder是二叉树的中序遍历,postorder是同一棵树的后序遍历,请你构造并返回这颗二叉树。classSolution{public:TreeNode*buildTree(vector<int>&inorder,vector<int>&postorder){if(postorder.size()==0)......
  • 1145. 二叉树着色游戏
    题目链接:1145.二叉树着色游戏方法:分类解题思路(1)\(x\)节点将二叉树分成了\(3\)部分,分别是父节点子树、左子树、右子树(节点数分别为n1n2n3);(2)为了使得二号玩家染色尽可能的多,应该让\(y\)选择在\(x\)相邻的节点。若存在以下一种情况,则二号玩家稳赢,n1>n2+n3+1||......
  • 257. 二叉树的所有路径
    给定一个二叉树,返回所有从根节点到叶子节点的路径。说明:叶子节点是指没有子节点的节点。classSolution{private:voidtraversal(TreeNode*cur,stringpath,vector<string>&res){path+=std::to_string(cur->val);if(cur->left==nullptr&......
  • 树:剑指 Offer 68 - II. 二叉树的最近公共祖先
    题目描述:给定一个二叉树,找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树T的两个结点p、q,最近公共祖先表示为一个结点x,满足x是p、q的祖先且x的深度尽可能大(一个节点也可以是它自己的祖先)。” 例如,给定如下二叉树: root= ......
  • 树:剑指 Offer 55 - II. 平衡二叉树
    题目描述:输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。示例1:  示例2:  限制:0<=树的结点个数<=10000 方法基于以下性质推出: 此树的深度 等于 左子树的深度 与 ......