一、树
1、树(Tree)是n(n≥0)个结点的有限集。
n=O时称为空树。在任意一棵非空树中:(1)有且仅有一个特定的称为根(Root)的结点;(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、......、Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)
2、树的结点包含一个数据元素及若干指向其子树的分支。
结点拥有的子树数称为结点的度(Degree)。度为0的结点称为叶结点(Leaf)或终端结点;度不为0的结点称为非终端结点或分支结点。除根结点之外,分支结点也称为内部结点。树的度是树内各结点的度的最大值。
3、线性结构与树结构的区别
(1)线性结构
·第一个数据元素:无前驱
最后一个数据元素:无后继
·中间元素:一个前驱一个后继
(2) 树结构
·根结点:无双亲,唯一
·叶结点:无孩子,可以多个
·中间结点:一个双亲多个孩子
二、二叉树
1、二叉树(Binary Tree)
二叉树是n(n≥0)个结点的有限集合,该集合或者为空集(称为空二叉树)。或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
2、二叉树特点:
(1)每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。注意不是只有两棵子树,而是最多有。没有子树或者有一棵子树都是可以的。
(2)左子树和右子树是有顺序的,次序不能任意颠倒。
(3)即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。
3、二叉树具有五种基本形态:
空二叉树、只有一个根结点、根结点只有左子树、根结点只有右子树、根结点既有左子树又有右子树。
4、满二叉树
在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上。
满二叉树的特点有:
(1)叶子只能出现在最下一层。出现在其他层就不可能达成平衡。
(2)非叶子结点的度一定是2。
(3)在同样深度的二叉树中,满二叉树的结点个数最多,叶子数最多。
5.完全二叉树
对一棵具有n个结点的二叉树按层序编号,如果编号为i (1<i<n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树
完全二叉树的特点:
(1)叶子结点只能出现在最下两层。
(2)最下层的叶子一定集中在左部连续位置。
(3)倒数二层,若有叶子结点,一定都在右部连续位置。
(4)如果结点度为1,则该结点只有左孩子,即不存在只有右子树的情况。(5)同样结点数的二叉树,完全二叉树的深度最小。
6.性质
性质1:在二叉树的第i层上至多有2-1个结点(i>1)。
性质2:深度为k的二叉树至多有2-1个结点(k>1)。
cs
#include<head.h>
#include"tree.h"
#include"queue.h"
char tree[]={"ABGH###G##CF#D##I##"};
int idx = 0;
TNode_t *create_bin_tree()
{
TDataType data = tree[idx++];
if(data =='#')
{
return NULL;
}
TNode_t *pnode = malloc(sizeof(TNode_t));
if(NULL == pnode)
{
perror("fail malloc");
return NULL;
}
pnode->data = data;
pnode->pl = create_bin_tree();
pnode->pr = create_bin_tree();
return pnode;
}
void pre_order(TNode_t *proot)
{
if(NULL == proot)
{
return ;
}
printf("%c ",proot->data);
pre_order(proot->pl);
pre_order(proot->pr);
}
void mid_order(TNode_t *proot)
{
if(NULL == proot)
{
return ;
}
mid_order(proot->pl);
printf("%c ",proot->data);
mid_order(proot->pr);
}
void pos_order(TNode_t *proot)
{
if(NULL == proot)
{
return ;
}
pos_order(proot->pl);
pos_order(proot->pr);
printf("%c ",proot->data);
}
int cnt_tree(TNode_t *proot)
{
if(NULL == proot)
{
return 0;
}
return cnt_tree(proot->pl) + cnt_tree(proot->pr) +1;
}
int get_tree_layer_cnt(TNode_t *proot)
{
if(NULL == proot)
{
return 0;
}
int cntl = get_tree_layer_cnt(proot->pl);
int cntr = get_tree_layer_cnt(proot->pr);
return cntl > cntr ? cntl + 1 : cntr + 1;
}
void destroy_tree(TNode_t *proot)
{
if (NULL == proot)
{
return ;
}
destroy_tree(proot->pl);
destroy_tree(proot->pr);
free(proot);
}
/*调用了队列*/
void layer_order(TNode_t *proot)
{
QDataType outdata;
Queue_t *pque = create_queue();
if (NULL == pque)
{
printf("fail create_queue\n");
return ;
}
push_queue(pque, proot);
while (!is_empty_queue(pque))
{
pop_queue(pque, &outdata);
printf("%c ", outdata->data);
if (outdata->pl != NULL)
{
push_queue(pque, outdata->pl);
}
if (outdata->pr != NULL)
{
push_queue(pque, outdata->pr);
}
}
destory_queue(pque);
}