树
1.1关于树的一些基本念
(1)度数:一个节点的子树的个数
(2)树度数:树中节点的最大度数
(3)叶节点或终端节点: 度数为零的节点
(4)分支节点:度数不为零的节点
(5)内部节点:除根节点以外的分支节点 (去掉根和叶子)
(6)节点层次: 根节点的层次为1,根节点子树的根为第2层,以此类推
(7)树的深度或高度: 树中所有节点层次的最大值
1.2 二叉树 (Binary Tree)
二叉树节点最大的度数2,是n(n≥0)个节点的有限集合,
它或者是空集(n=0),或者是由一个根节点以及两棵互不相交的、分别称为左子树和右子树的二叉树组成。二叉树与普通有序树不同,二叉树严格区分左孩子和右孩子,即使只有一个子节点也要区分左右。
1.2.2 二叉树性质(重点)
(1)二叉树第k(k>=1)层上的节点最多为2的k-1次幂个节点。
2^(k-l)
(2)深度为k(k>=1)的二叉树最多有2的k次幂-1个节点
2^k - 1
(3)在任意一棵二叉树中,树叶的数目比度数为2的节点的数目多一。n0=n2+1
(4)满二叉树和完全二叉树
1)满二叉树: 深度为k(k>=1)时节点为2^k - 1(2的k次幂-1)
2)完全二叉树:只有最下面两层有度数小于2的节点,且最下面一层的叶节点集中在最左边的若干位置上。
问题:深度为k的最小完全二叉树节点个数最少为多少?2^(k-1) -1 + 1
1.2.3 二叉树的存储结构
(1)二叉树的顺序存储结构 (数组存储)
顺序存储结构:完全二叉树节点的编号方法是从上到下,从左到右,根节点为1号节点。设完全二叉树的节点数为n,某节点编号为i
当i>1(不是根节点)时,有父节点,其编号为i/2;
当2i<=n时,有左孩子,其编号为2i ,否则没有左孩子,本身是叶节点;
当2i+1<=n时,有右孩子,其编号为2i+1 ,否则没有右孩子;
有n个节点的完全二叉树可以用有n+1 个元素的数组进行顺序存储,节点号和数组下标一一对应,下标为零的元素不用。
1.2.4二叉树的遍历(重点)
前序: 根 ----> 左 -----> 右
中序: 左 ----> 根 -----> 右
后序: 左 ----> 右 -----> 根
(2) 二叉树的链式存储
二叉树节点结构体定义:数据 左子节点地址 右子节点地址
typedef char tree_datatype;
typedef struct tree_t
{
tree_datatype data;//数据域
struct tree_t *lchild;//左子节点地址
struct tree_t *rchild;//右子节点地址
}bitree_t;
操作:
1.创建一棵树
2.遍历:前序 中序 后序 层次
1.3 二叉树的链式存储
//1.创建一棵树
bitree_t *createBitree(void)
{
char ch;
bitree_t *r=NULL;
scanf("%c",&ch);
if(ch == '#')
return NULL;
r=(bitree_t *)malloc(sizeof(bitree_t));
if(r == NULL)
{
printf("malloc bitree node error.\n");
return NULL;
}
//初始化
r->data=ch;
r->lchild=createBitree();
r->rchild=createBitree();
return r;
}//ABD###CE#G##F##
//2.前序遍历
void preOder(bitree_t *r)
{
if(r == NULL)
return;
printf("%c",r->data);
preOder(r->lchild);
preOder(r->rchild);
}
//3.中序遍历
void inOder(bitree_t *r)
{
if(r == NULL)
return;
inOder(r->lchild);
printf("%c",r->data);
inOder(r->rchild);
}
//4.后序遍历
void postOder(bitree_t *r)
{
if(r == NULL)
return;
postOder(r->lchild);
postOder(r->rchild);
printf("%c",r->data);
}
//5.层次遍历
void levelOder(bitree_t *r)
{
if(r == NULL)
return;
//1.创建一个队列
queue_t *p=createLinkQueue();
//2.让根节点地址入队
inQueue(p,r);
while(!isEmptyQueue(p))
{
r=outQueue(p);
printf("%c",r->data);
if(r->lchild != NULL)
inQueue(p,r->lchild);
if(r->rchild != NULL)
inQueue(p,r->rchild);
}
}