数据结构-树与二叉树

一. 树

1.1 树的概念

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。有一个特殊的结点,称为根结点,根节点没有前驱结点除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、......、Tm,其中每一个集合Ti(1<= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继因此,树是递归定义的。

根节点: 最顶层的节点

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

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

树的深度: 树的层数

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

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

二. 二叉树

2.1 二叉树的概念

**二叉树:**度为2的树是一个二叉树

2.2 两种特殊的二叉树

2.2.1. 满二叉树:

1、一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。

2、也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1,则它就是满二叉树。

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

4、满二叉树第k层的节点数:2^(k-1) 总的节点数:(2^k)-1

2.2.2. 完全二叉树:

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

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

2、完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树满二叉树是一种特殊的完全二叉树

一道计算题:

一个完全二叉树的节点总是为5428,求其叶子节点的个数:

2.3 二叉树的遍历

2.3.1深度优先

1. 前序遍历

顺序:根->左->右

结果:ABEFIDHMJ

2. 中序遍历

顺序:左->根->右

结果:EBFIAMHD

3. 后序遍历

顺序:左->右->根

结果:EIFBMHJDA

2.3.2 广度优先

1. 层序遍历

从上至下,从左至右,逐层遍历

结果:ABDEFHJIM

三. 二叉树的代码实现

3.1 二叉树的声明

cpp 复制代码
typedef char TDataType_t;
typedef struct treenode{
    TDataType_t data;
    struct treenode *pl;
    struct treenode *pr;
}TNode_t;

3.2 二叉树的遍历

3.2.1 前序

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

3.2.2 中序

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

3.2.3 后序

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

3.2.4 层序

二叉树层序遍历的思想:使用队列的先入先出 特性,将当前节点入队列,此节点出队列时,将其左右子树的两个节点(判断不为空)带入的队列里,若队列不为空,则一直循环重复此操作即可。

cpp 复制代码
//二叉树的层序遍历
void level_order(TNode_t *proot)
{
    if(proot == NULL){
        return;
    }
    Queue_t *pqueue = creat_queue();//创建队列
    if(pqueue == NULL){
        return;
    }
    TNode_t *ptemp;
    queue_push(pqueue, proot);//入队
    while(!is_empty_queue(pqueue)){
        queue_pop(pqueue, &ptemp);//出队
        printf("%c",ptemp->data);
        if(ptemp->pl){
            queue_push(pqueue, ptemp->pl);
        }
        if(ptemp->pr){
            queue_push(pqueue, ptemp->pr);
        }
    }
    destroy_queue(&pqueue);//销毁队列
}

3.3 二叉树的销毁

cpp 复制代码
//销毁二叉树
void destroy_bin_tree(TNode_t **pproot)
{
    if(*pproot == NULL){
        return;
    }
    else{
        destroy_bin_tree(&((*pproot)->pl));
        destroy_bin_tree(&((*pproot)->pr));
        free(*pproot);
        *pproot = NULL;
    }
}

3.4 获取二叉树的节点个数

cpp 复制代码
//二叉树节点个数
int get_tree_node_num(TNode_t *proot)
{
    if(proot == NULL){
        return 0;
    }
    else{
        return 1 + get_tree_node_num(proot->pl) + get_tree_node_num(proot->pr); 
    }
}

3.5 获取二叉树的最大深度

cpp 复制代码
//获取二叉树最深深度
int get_tree_max_deep(TNode_t *proot)
{
    if(proot == NULL){
        return 0;
    }
    int a = get_tree_max_deep(proot->pl);
    int b = get_tree_max_deep(proot->pr);
    return a > b ? a + 1 : b + 1;
}
相关推荐
Chen_harmony12 小时前
二十二、动态内存管理
c语言·数据结构·算法
孬甭_13 小时前
栈和队列
c语言·数据结构
周末也要写八哥13 小时前
经典算法题之删列造序(二)
数据结构·算法
枕星而眠13 小时前
数据结构八大排序详解(二):四大高阶排序(归并/快排/堆/基数)
数据结构
LuminousCPP13 小时前
C 语言通讯录补坑篇:终版遗留 Bug 修复,解决修改姓名输入错乱问题
c语言·开发语言·数据结构·经验分享·笔记·顺序表
z落落13 小时前
C# 数组高阶函数(Find/FindAll/Exists/ForEach/All/Any)
javascript·数据结构·算法
Lazionr13 小时前
二叉树入门:从概念到代码实现
c语言·数据结构
星轨初途13 小时前
【C++ 进阶】list 核心机制解析及 vector 巅峰对决
开发语言·数据结构·c++·经验分享·笔记·list
山峰哥14 小时前
索引策略与SQL优化:从Explain对比到生产调优的完整方法论
android·java·数据库·sql·性能优化·深度优先