二叉树

二叉树(Binary Tree)----是n(n >=0)个结点的有限集合,该集合或者为空集,或者由一个根结点和两颗互不相交的,分别称为根结点的左子树和右子树的二叉树组成。

特点:

1.每个结点最多有两科子树,所以二叉树中不存在度大于2的结点。

2.左子树和右子树是有顺序的,次序不能任意颠倒。

3.即使树中某结点只有一颗子树,也要区分它是左子树还是右子树。

二叉树的5种基本形态:

1.空二叉树

2.只有一个根结点

3.根结点只有左子树

4.根结点只有右子树

5.根结点既有左子树又有右子树

特殊二叉树

1.斜树

顾名思义,斜树就是一定要斜的树。所有的结点都只有左子树的二叉树叫左斜树。所有结点都是只有右子树的二叉树叫右斜树。

2.满二叉树

在一颗二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层,这样的二叉树称为满二叉树。

3.完全二叉树

对一颗具有n个结点的二叉树按层序编号,如果编号为i(i =<i =<n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全不同,则这棵二叉树称为完全二叉树。

完全二叉树的特点:

1.叶子结点只能出现在最下两层

2.最下层的叶子一定集中在左部连续位置。

3.倒数二层,若有叶子结点,一定都在右部连续位置

4.如果结点度为1,则该结点只有左孩子,即不存在只有右子树的情况

5.同样结点数的二叉树,完全二叉树的深度最小。

所以给了我们一个判断某二叉树是否是完全二叉树的办法,那就是看着树的示意图,心中默默给每个结点按照满二叉树的结构逐层顺序编号,如果编号出现空挡,就说明不是完全二叉树,否则就是。

二叉树的性质:

性质1。 在二叉树的第i层上至多有2^(i-1)个结点。

性质2.深度为k的二叉树至多有2^k - 1个结点。

性质3.对任何一颗二叉树T,如果其终端结点数为n0,度为2的结点数位n2,则n0 = n2 +1

性质4.具有n个结点的完全二叉树的深度为[log2(n) +1]([]在这里表示向下取整)。

性质5.如果对一颗有n个结点的完全二叉树的结点按层序编号,对任意结点i有:

1.如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点[i/2](这里[]表示向下取整)

2.2i >n,则结点i无左孩子,否则其左孩子是结点2i

3.如果2i + 1 >n,则结点i无右孩子,否则其右孩子是结点2i + 1.

二叉链表存储:

二叉树每个结点最多有两个孩子,所以为它设计一个数据域和两个指针域是比较自然的想法,称这样的链表而二叉链表。其结构如下:


其中,data是数据域,lchild和rchild就是指针域,分别存放指向左孩子和右孩子的指针。以下是二叉树的链式存储的结构代码:

typedef struct BiTNode
{
      TElemType data;
       struct BiTNode *lchild,rchild;
} BiTNode , *BiTree;
结构示意图如下:


遍历二叉树

二叉树的遍历----指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。

1.前序遍历

若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。如下图,遍历顺序为:ABDGHCEIF


代码如下:

void  PreOrderTraverse(BiTree T)
{
	if(T == NULL)
		return;
	printf("%c ",T->data);
	PreOrderTraverse(T->lchild);
	PreOrderTraverse(T->rchild);
}

中序遍历:

规则是,若树为空,则空操作返回,否则从根结点开始,中序遍历根结点的左子树,然后是访问根结点,最后是中序遍历右子树。遍历顺序如下:GDHBAEICF


实现代码如下:

void  InOrderTraverse(BiTree T)
{
	if(T == NULL)
		return;
	InOrderTraverse(T->lchild);
	printf("%c ",T->data);
	InOrderTraverse(T->rchild);
}


后序遍历:

规则是若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。遍历的顺序为:GHDBIEFCA



实现代码如下:

void PostOrderTraverse(BiTree T)
{
	if(T == NULL)
		return;
	PostOrderTraverse(T->lchild);
	PostOrderTraverse(T->rchild);
	printf("%c ",T->data);
}

层序遍历:

规则是若树为空,则空操作返回,否则从树的第一层,也就是根结点开始访问,从上而下逐层遍历,在用一层中,按从左到右的顺序对结点逐个访问。遍历顺序为:ABCDEFGHI


二叉树的建立:

对于普通的二叉树,我们进行扩展,并对扩展的结点作为虚结点引入一个特定的值表示“#”,扩展后的二叉树叫做扩展二叉树。如下图所示:


这样我们就可以生产一颗二叉树了,假设二叉树的结点均为一个字符,输入:AB#D##C##

void CreateBiTree(BiTree *T)
{
	TElemType ch;
	scanf("%c",&ch);
	if(ch == '#')
		*T = NULL;
	else{
		*T = (BiTree)malloc(sizeof(BiTree));
		if(!*T)
			exit(OVERFLOW);
		(*T)->data = ch;
		CreateBiTree(&(*T)->lchild);
		CreateBiTree(&(*T)->rchild);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值