一. 树
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;
}