树的基础知识

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);
	}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值