高级数据结构 | 二叉树判定— 是否为?满二叉树、完全二叉树、(后面待更新... ...)BST树、平衡二叉树、对称二叉树、子树、相同的树 ...


是否是满二叉树。

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

一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。并且,一个满二叉树的第K层,结点总数是(2^k) -1。

从数学上看,满二叉树的各个层的结点数形成一个首项为1,公比为2的等比数列。
1 2 4 8 16...   . . . {1、2、4、8、16 ...\ ... } ,每一层的结点数为上上一层的2倍,并且
{ n 1 } = { n 1 } \{前 n-1 层的结点数\} = \{第 n 层的结点数 - 1\}

F
A
B
E
C
D
G

使用层序遍历判断每层是否达到最大值。

bool IS_FULL_BinTree(struct BtNode* ptr)
{
	bool res = true;
	if (ptr == NULL) return res;	// 空树也是满二叉树
	std::queue<struct BtNode*> que;
	que.push(ptr); 
	int floor = 1;		// 层
	while (!que.empty())
	{
		int i = 0;		// 记录该层元素的个数
		while (!que.empty() && i < floor)
		{
			ptr = que.front(); que.pop();
			if (ptr->leftchild != NULL)
			{
				que.push(ptr->leftchild);
			}
			if (ptr->rightchild != NULL)
			{
				que.push(ptr->rightchild);
			}
			++i;
		}
		if (i < floor)	// 该层元素不够,树不满
		{
			res = false;
			break;
		}
		floor *= 2;
	}
	return res;
}

使用递归方法判断相当方便,只是执行效率要差得多。思路:左右子树皆为满二叉树且深度相同。

bool Is_Full_BinTee(struct BtNode* ptr)
{
	return (ptr == NULL) || (Is_Full_BinTee(ptr->leftchild) && Is_Full_BinTee(ptr->rightchild)
							&& GetDepth(ptr->leftchild) == GetDepth(ptr->rightchild));
}

是否是完全二叉树。

完全二叉树可以理解为满二叉树的一种特殊情况,可视为最后一层的结点从右至左连续缺省若干个结点。比如下面这棵树。

F
A
B
E
C
D
G
A
B
E
C
D

左边为一颗满二叉树,从它的最后一层缺省掉结点G、F之后就是一颗完全二叉树。并且一个满二叉树也是一个完全二叉树。

思路分析:观察下图中所有叶子结点。

F
A
B
E
C
D
G
A
B
E
C
D
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL

如果我们在遍历时,把二叉树中指向NULL的结点也遍历的话,图左的满二叉树按照层序遍历输出 : A ,     B , E 2 ,     C , D , F , G 4 ,     N U L L , N U L L , N U L L , N U L L , N U L L , N U L L , N U L L , N U L L 8 {A,\ \ \ \underbrace{B,E}_{2},\ \ \ \underbrace{C,D,F,G}_{4},\ \ \ \underbrace{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}_{8}}

图左的满二叉树按照层序遍历输出:
A ,     B , E 2 ,     C , D , N U L L , N U L L 4 ,     N U L L , N U L L , N U L L , N U L L 4 {A,\ \ \ \underbrace{B,E}_{2},\ \ \ \underbrace{C,D,NULL,NULL}_{4},\ \ \ \underbrace{NULL,NULL,NULL,NULL}_{4}}

我们可以发现,完全二叉树在层次遍历时,最后输出的内容为一连串不间断的 NULL

而如果是非完全二叉树就会出现如 A , B , . . .   . . .   n u l l , . . .   . . . n u l l n n u l l , N , n u l l , . . .   . . . n u l l m n u l l {{A,B,...\ ...\ \overbrace{\underbrace{null,... \ ... null}_{n*null},N, \underbrace{null,...\ ... null}_{m*null}}}} 的情况。因为完全二叉树是由满二叉树从左至右连续缺省得到,因此,在最后的n个null结点中是不会突然出现有效结点的,如公式中的 N 结点。

使用层序遍历,检查队列中最后的元素是否为一串连续的NULL结点。

bool IS_Comp_BinTree(struct BtNode* ptr)
{
	bool res = true;
	if (ptr == NULL) return res;
	std::queue<struct BtNode*> que;
	que.push(ptr);
	while (!que.empty())
	{
		ptr = que.front(); que.pop();
		if (ptr == NULL)	// null开始
		{
			while (!que.empty())
			{
				ptr = que.front(); que.pop();
				if (ptr != NULL)	// 检查是否全为null
				{
					res = false;
					break;
				}
			}
		}else
		{
			que.push(ptr->leftchild);
			que.push(ptr->rightchild);
		}

	}
	return res;
}

先留着,以后更新 … …


是否是BST树

是否是平衡二叉树

是否是对称二叉树

是否是一棵树的子树

两个二叉树是否相同

原创文章 131 获赞 128 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43919932/article/details/105564077