数据结构 树 二叉树

一种一对多的结构

有一个根节点和若干个分支节点构成的具有一对多关系的数据的集合

根节点:最顶层的节点

分支节点:有子节点的节点

叶子节点(终端节点):没有子节点的节点

树的深度:树的层数

树的广度(度):树中节点的度最大的值即为该树的度

节点的度:节点的子节点个数

二叉树

度为2的树是一个二叉树

满二叉树:在不增加层数的前提下,无法增加一个节点,这种二叉树是一个满二叉树

满二叉树:

第K层节点数:2^(K-1)

K层总节点数:2^K-1

完全二叉树:在满二叉树的基础上,按照从上至下,从左至右的方式增加若干个连续的节点。

满二叉树一定是一颗完全二叉树

二叉树的遍历

前序遍历:根,左子树,右子树 ABEFIDHMJ

中序遍历:左子树,根,右子树 EBFIAMHDJ

后序遍历:左子树,右子树,根 EIFBMHJDA

以上三种深度优先

层序遍历:从上至下,从左至右,逐层遍历 ABDEFHJIM 广度优先

前序遍历:ABC

前序 : ABC 后序:CBA

已知一个前序遍历和中序遍历结果,可以确定一颗唯一的二叉树

已知一个后序遍历和中序遍历结果,可以确定一颗唯一的二叉树

前序:ABEFIDHMJ

中序:EBFIAMHDJ

借助# , 不打印#

封装树节点结构体

数据,左子节点指针,右子节点指针

cpp 复制代码
typedef char DataType;


typedef struct trnode
{
    DataType data;
    struct trnode *pl;
    struct trnode *pr;
}TNode_t;

创建二叉树函数

二叉树先序序列,#代表空节点

idx 全局遍历下标

返回二叉树结点结构体指针的函数

调用malloc申请存放结点的堆内存,进行是否申请成功判断

递归创建左子节点,递归创建右子节点

cpp 复制代码
DataType tree[] = {"ABE##F#I##DHM###J##"};
int idx = 0;

TNode_t*create_bin_tree()
{
    DataType data = tree[idx++];//取下一个字符,下标后移
    if('#' == data)
    {
        return NULL;//遇到#,表示空结点,返回NULL
    }

    TNode_t*pnode = malloc(sizeof(TNode_t));
    if(NULL == pnode)
    {
        printf("malloc error\n");
        return NULL;
    }
    pnode->data = data;
    pnode->pl = create_bin_tree();
    pnode->pr = create_bin_tree();
    return pnode;
}

前序遍历输出函数

根,左子树,右子树

传入参数为根节点指针,进行判断传入的根节点是否为空节点,不为空,

打印输出根节点,递归打印输出左子节点,递归打印输出右子节点

cpp 复制代码
void pre_order(TNode_t*proot)
{
    if(NULL == proot)
    {
        return ;
    }
    printf("%C",proot->data);
    pre_order(proot->pl);
    pre_order(proot->pr);

}

中序遍历输出函数

左子节点,根,右子节点

传入参数为根节点指针,进行判断传入的左子节点是否为空,

递归打印输出左子节点,打印输出根节点,递归打印输出右子节点

cpp 复制代码
void mid_order(TNode_t*proot)
{
    if(NULL == proot)
    {
        return;
    }
    mid_order(proot->pl);
    printf("%c",proot->data);
    mid_order(proot->pr);
}

后序遍历输出函数

左子节点,右子节点,根节点

传入参数为根节点指针,进行判断传入的根节点是否为空

递归打印输出左子节点,递归打印输出右子节点,打印输出根节点

cpp 复制代码
void pos_order(TNode_t*proot)
{
    if(NULL == proot)
    {
        return;
    }
    pos_order(proot->pl);
    pos_order(proot->pr);
    printf("%c",proot->data);
}

计算二叉树总结点数函数

传入参数为树的根节点指针

根节点为空,直接退出

递归累加根节点+左子节点+右子节点

cpp 复制代码
int get_tree_node_cnt(TNode_t*proot)
{
    if(NULL == proot)
    {
        return 0;
    }
    return 1+get_tree_node_cnt(proot->pl)+get_tree_node_cnt(proot->pr);
}

销毁二叉树

传入参数为根节点指针,进行判断根节点是否为空

递归销毁左子节点,递归销毁右子节点,销毁根节点

释放指针内存空间后,将指针置空,避免成为野指针

cpp 复制代码
void destory_tree(TNode_t*proot)
{
    if(NULL == proot)
    {
        return;
    }
    destory_tree(proot->pl);
    destory_tree(proot->pr);
    free(proot);
    proot = NULL;
}

层序遍历函数

借助队列

传入参数为根节点指针,创建队列(先进先出),定义局部变量,表示出队数据

根节点指针入队,以队列不为空为条件,开始循环

出队节点,打印输出节点指针指向内容,

若左、右子节点不为空,入队左、右子节点

队列为空,循环结束,销毁队列

cpp 复制代码
void layer_node(TNode_t*proot)
{
   Queue_t*pqueue = NULL;

   Datatype_t outdata;
   pqueue = create_link();

   if(NULL == pqueue)
   {
    return ;
   }

    input_queue(pqueue, proot);

    while(!is_empty_queue(pqueue))
    {
        output_queue(pqueue, &outdata);
        printf("%c",outdata->data);
        if(outdata->pl!= NULL)
        {
            input_queue(pqueue, outdata->pl);
        }
        if(outdata->pr!= NULL)
        {
            input_queue(pqueue, outdata->pr);
        }
    }

    destory_queue(&pqueue);

    return ;
}
相关推荐
WWW65261 小时前
代码随想录 打卡第四十七天
数据结构·算法·leetcode
cpp_25011 小时前
P10722 [GESP202406 六级] 二叉树
数据结构·c++·算法·题解·洛谷·树形结构·gesp六级
c238562 小时前
map和set
数据结构·c++
小欣加油4 小时前
leetcode239 滑动窗口最大值
数据结构·c++·算法·leetcode·哈希算法
炸薯条!4 小时前
二叉树的链式表示
数据结构·算法
CHHH_HHH4 小时前
【C++】二叉搜索树全面升级,深度剖析AVL树
开发语言·数据结构·c++·算法·stl
不会就选b4 小时前
数据结构之双向循环链表
数据结构·链表
悠仁さん4 小时前
数据结构OJ 简单算法题
数据结构
WBluuue5 小时前
数据结构与算法:树上启发式合并
数据结构·c++·算法·启发式算法