树的深度和广度遍历

这里写图片描述

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define MAX_SIZE 100 //队列的最大容量
/*
树:树是一种自定义结构.由n(n>0)个节点组成,有且只有一个节点作为树根.n-1个节点组成一个子树.树是一种递归定义.
节点为0的树称为空树
树节点由存储数据和指向其子树指针(n>=1)
树最大特点控制目标数比较次数,可以实现在O(logn a ,n>=1).提高搜索效率
树是一个无环的图
树名词:
1.子节点:节点指向一个个子树,子树的根称为子节点
2.终端节点(叶子节点):没有任何子树的节点,一般是树对下层节点
3.节点度:节点存在子树个数(一般为 0 1 2 3 ...)
4.树广度:节点度最大值
5.树深度:从树根到终端节点的最大层次数
有树度不定,导致程序中不好去定义一个通用树节点类型.一般我们使用二叉树
二叉树:树广度为2(节点最大度为2)
左孩子:节点左边的子树
右孩子:节点右边的子树
一般存在下面5种形式的二叉树:
1.空二叉树
2.只一个根节点
3.全左
4.全右
5.根左右
二叉树属性:
1.非空二叉树的第n层最大节点数是:2^(n-1)(n>=1 第几层)
2.非空二叉树树最大的节点树是:2^n-1(n>=1 树层次树)
3.完全二叉树:树的节点度可以是0,1,2.如果树的节点度为1,优先存在左子树.(树存在节点编号与对应满二叉树节点编号一致)
4.满二叉树:树的节点度只能是0 或2,满二叉树是一个完全二叉树
5.如果一个二叉树存在度为2节点数是n2,度为1节点数是n1,度为0节点数为n0,n2 n1 n0存在一个怎样关系?
n0=n2+1
树总结点数:n2+n1+n0  =       2*n2+n1+1 --> n0=n2+1
*/

//定义树的节点
typedef struct tree_node
{
    char value;
    struct  tree_node* lchild;
    struct  tree_node* rchild;
}tree_node;

//定义队列节点
typedef struct  node
{
    tree_node* ptr_node;
    struct node * next;
}node;

//定义队列
typedef struct queue
{
    node* front;
    node* tail;
    int size;
    int capacity;
}queue;

//初始化队列
void  init_queue(queue *  ptr_queue)
{
    ptr_queue->front=ptr_queue->tail=NULL;
    ptr_queue->size=0;
    ptr_queue->capacity=MAX_SIZE;
}
//入队
void   push_queue(queue*  ptr_queue,tree_node *  ptr_node)
{
    if(!is_queue_full(ptr_queue))
    {
        node * ptr_new=(node*)malloc(1*sizeof(node));
        assert(ptr_new != NULL);
        ptr_new->ptr_node=ptr_node;
        ptr_new->next=NULL;

        if(ptr_queue->front==NULL)
        {
            ptr_queue->front=ptr_new;      
        }
        else
        {
            ptr_queue->tail->next=ptr_new;
        }
        ptr_queue->size++;
        ptr_queue->tail=ptr_new;
        ptr_new=NULL;
    }
    else
    {
        printf("queue is full\n");
    }   
}
//出队
void  pop_queue(queue * ptr_queue)
{
    if(!is_queue_empty(ptr_queue))
    {
        node *  ptr_tmp=ptr_queue->front;
        ptr_queue->front=ptr_queue->front->next;
        if(ptr_queue->front==NULL)
        {
            ptr_queue->tail=NULL;
        }
        ptr_queue->size--;
        free(ptr_tmp);
        ptr_tmp=NULL;
    }
    else
    {
        printf("queue is empty\n");
    }
}

//队列是否满
int  is_queue_full(queue*  ptr_queue)
{
    if(ptr_queue->size>ptr_queue->capacity)
    {
        return 1;
    }
    return 0;
}
//队列是否空
int   is_queue_empty(queue*  ptr_queue)
{
    if(ptr_queue->front==NULL &&  ptr_queue->tail==NULL)
    {
        return 1;
    }
    return 0;
}
//返回队列元素个数
int   get_queue_cnt(queue * ptr_queue)
{
    return  ptr_queue->size;
}
//返回队首
tree_node*  get_queue_front(queue * ptr_queue)
{
    if(!is_queue_empty(ptr_queue))
    {
        return  ptr_queue->front->ptr_node;
    }
    return NULL;
}
//返回队尾
tree_node*   get_queue_tail(queue*  ptr_queue)
{
    if(!is_queue_empty(ptr_queue))
    {
        return  ptr_queue->tail->ptr_node;
    }
    return NULL;
}


//定义树结构

//构建一个树
tree_node*  init_binary_tree()
{
    char value;
    scanf("%c",&value);
    getchar();
    tree_node* root;
    if(value=='q')//'q输入为结束字符'
    {
        root=NULL;
    }
    else
    {
        root=(tree_node*)malloc(1*sizeof(tree_node));
        root->value=value;
        root->lchild=init_binary_tree();
        root->rchild=init_binary_tree();
    }
    return root;    
}


//树广度遍历:从根开始访问,按照根节点左右顺序访问.每次把同层节点左右孩子访问完毕.再访问下一层,所以用队列实现
void  print_broadcast_tree(tree_node  * root)
{
    queue  qu;
    init_queue(&qu);
    assert(root != NULL);
    if(root!=NULL)
    {
        push_queue(&qu,root);
    }
    while(root!=NULL ||  !is_queue_empty(&qu))
    {        
        root=get_queue_front(&qu);
        printf("%c\t",root->value);
        pop_queue(&qu);
        if(root->lchild!=NULL)
        {
            push_queue(&qu,root->lchild);
        }
        if(root->rchild!=NULL)
        {
            push_queue(&qu,root->rchild);
        }        
        root=NULL;
    }
}

//获取树深度,递归(也就是栈)实现
int   get_depth_tree(tree_node * root)
{
    int left=0,right=0;
    if(root!=NULL)
    {
        left=get_depth_tree(root->lchild)+1;
        right=get_depth_tree(root->rchild)+1;
    }
    return left>right?left:right;
}


int main(int argc, char const *argv[])
{
    tree_node* root=init_binary_tree();
    printf("树的广度为:");
    print_broadcast_tree(root);
    printf("\n");
    printf("树的深度为:%d\n",get_depth_tree(root));
    printf("\n");
    return 0;
}

运行结果:
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值