浅谈二叉树

Posted yhz-albert

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈二叉树相关的知识,希望对你有一定的参考价值。

二叉树

二叉树不是树的一种特殊情形,尽管其与树有许多相似之处,但树和二叉树有两个主要差别:

1. 树中结点的最大度数没有限制,而二叉树结点的最大度数为2

2. 树的结点无左、右之分,而二叉树的结点只有左、右之分

 

下图即为一个典型是二叉树!!!

技术图片

接下来就来分析这个图:

在这“棵”树上

根结点 ------ F

叶子结点 ------ A 、B 、H 、 M

子结点 ----- 除了 根结点F 的其他结点

父亲结点 ----- 除了 叶子结点 的其他结点

兄弟结点 ----- 【C 、E】【A 、D】【H 、G】

堂兄结点 ----- 【B 、M】【A 、H】【D  、G】

深度 ----- 这棵树的深度为4

......像这样的专业术语还有很多,这里就列举了几个常用的。

 

 接着就来看一下二叉树的几种形态:

 

技术图片

A ------ 一颗空二叉树。(记住:没有东西,也可以是一颗二叉树,只不过是一颗空树)

B ------ 有一个结点的二叉树。(这一个结点既是根结点,也是叶子结点)

C ------ 只有左子树。

D ------ 只有右子树。

E ------ 完全二叉树。(这里完全二叉树只一种特殊的二叉树)

所以这样可以定义二叉树:

struct Binary_tree //构建二叉树 

	int Date ; //结点数值 
	struct Binary_tree *lchild ; //左子树 
	struct Binary_tree *rchild ; //右子树 (这里左右子树也可以看成二叉树) 
 *Bitree ;

介绍一下特殊的二叉树:

1、完全二叉树:

技术图片

 

定义:若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

一棵二叉树至多只有最下面的两层上的结点的度数可以小于2,并且最下层上的结点都集中在该层最左边的若干位置上,则此二叉树成为完全二叉树,并且最下层上的结点都集中在该层最左边的若干位置上,而在最后一层上,右边的若干结点缺失的二叉树,则此二叉树成为完全二叉树。

2、满二叉树:

技术图片

定义:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点二叉树。

一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。(这里是国内的说法,国外的说法不同)

3、平衡二叉树:

技术图片

 

 定义:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

平衡二叉树或者是一棵空树,或者是具有以下性质的二叉排序树:(1)它的左子树和右子树的高度之差绝对值不超过1;(2)它的左子树和右子树都是平衡二叉树。

 以上三种为特殊的二叉树,都十分的特别,都具有一些性质。(这里就不详细的讲解了)

 

最后来讲一下二叉树的遍历:

遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。

由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。 

技术图片

遍历规则:
⑴访问结点本身(N),
⑵遍历该结点的左子树(L),
⑶遍历该结点的右子树(R)。
 
遍历方法:

一、 NLR:前序遍历

(Preorder Traversal 亦称(先序遍历))

——访问根结点的操作发生在遍历其左右子树之前。

⑴ 访问根(N)结点;
⑵ 遍历左(L)子树;
⑶ 遍历右(R)子树。
void NLR_PreTraversal ( Binary_tree *tree ) //先序遍历 

	if ( tree->Data == NULL )
	
		return;
	
	cout << tree->Data ;
	NLR_PreTraversal ( tree->lchild ) ;
	NLR_PreTraversal ( tree->rchild ) ;

二、 LNR:中序遍历

(Inorder Traversal)

——访问根结点的操作发生在遍历其左右子树之中(间)。

⑴遍历左(L)子树;
⑵访问根(N)结点;
⑶遍历右(R)子树。
void LRN_InoTraversal ( Binary_tree *tree ) //中序遍历 

	if ( tree->Data == NULL )
	
		return;
	
	LRN_InoTraversal ( tree->lchild ) ;
	cout << tree->Data ;
	LRN_InoTraversal ( tree->rchild ) ;

三、 LRN:后序遍历

(Postorder Traversal)

——访问根结点的操作发生在遍历其左右子树之后。

⑴遍历左(L)子树;
⑵遍历右(R)子树;
⑶访问根(N)结点。
void LRN_PosTraversal ( Binary_tree *tree ) //后序遍历 

	if ( tree->Data == NULL )
	
		return;
	
	LRN_PosTraversal ( tree->lchild ) ;
	LRN_PosTraversal ( tree->rchild ) ;
	cout << tree->Data ;

注:还有层序遍历,其实就只BFS(宽度优先搜索),这里就不单独提出来了。

 

 

以上即为我总结的二叉树基础内容。

以上是关于浅谈二叉树的主要内容,如果未能解决你的问题,请参考以下文章

面试官: 今天我们不谈二叉树, 谈谈你对二叉堆的理解?

再谈二叉树:三种遍历六种实现

再谈二叉树:三种遍历六种实现

算法漫游指北(第十三篇):二叉树的基本概念满二叉树完全二叉树二叉树性质二叉搜索树二叉树定义二叉树的广度优先遍历

树二叉树满二叉树完全二叉树遍历二叉树java实现

二叉树及特殊二叉树(满二叉树完全二叉树二叉排序树平衡二叉树)的定义和性质(附详细推理过程)