数据结构 树 二叉树

一种一对多的结构

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

根节点:最顶层的节点

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

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

树的深度:树的层数

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

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

二叉树

度为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 ;
}
相关推荐
青山木6 小时前
Hot 100 --- 搜索插入位置
java·数据结构·算法·leetcode
Livia要学习9 小时前
Python2和Python3字典底层原理
数据结构
青梅橘子皮9 小时前
STL---map/set... “家族“详解(从使用到底层)(1)
数据结构·算法
Adios7949 小时前
搜索二维矩阵 II
java·数据结构·算法
灵枢时代14 小时前
小程序在生鲜配送行业,如何设计夜间预约和次日达的订单处理流程?
数据结构·人工智能·小程序
一条大祥脚14 小时前
ABC468 扫描线|贡献法|二阶差分|线段树优化DP
数据结构·算法
mifengxing1 天前
LeetCode 189 轮转数组|3种解法拆解,从暴力到O(1)原地最优解
数据结构·算法·leetcode
MIngYaaa5201 天前
2026暑期牛客多校3 2026-7-24
数据结构·算法·000
2501_937860941 天前
Java 集合底层深度剖析:Map 与 Set、二叉搜索树、哈希表全解
java·数据结构·散列表
Hommy881 天前
【剪映小助手】字符串列表转对象接口(Str List To Obds)
数据结构·list·剪映小助手·视频剪辑自动化·剪映api·开源剪映小助手