判断一棵二叉树是否为完全二叉树

Posted 梅诺

tags:

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

1.完全二叉树的特点(来自专业定义)


看到上面完全二叉树的特点,我可以将其特点按照自己的理解归纳为以下几点:

(1):若二叉树最下面一层有节点出现,那么这个节点一定是是从左到右依次排列,若只有一个孩子,那么这个孩子一定是左孩子而不是右孩子(特殊情况,空树和只有根节点的树都是完全二叉树)。

(2)要么最后一层全为叶子节点,否则以它为根节点的孩子一定是从左依次排列的)。

2.解决这个问题的办法(全部采用广度优先遍历的方法进行遍历,并使用队列这个结构操作数据):

只要当前节点有一个孩子不为空,那么就将它的左右孩子都压入队列,出队列第一次到NULL节点时,做一个标记,直到队列为空后面都再无非空节点出现,那么它就一定是完全二叉树;反之若第一次出现NULL节点后再出现非空节点,那么它一定就不满足完全二叉树的定义。

3.代码实现

bool _IsCompleteTree(Node* root)
	
		if (root == NULL)
		
			return true;
		
		if (root->_left == NULL&&root->_right == NULL)
		
		return true;
		
		queue<Node*> q;
		bool flag = false;
		q.push(root);
		while (!q.empty())
		
			Node* Front = q.front();
			q.pop();
			if (Front != NULL && (Front->_left || Front->_right))
			
				q.push(Front->_left);
				q.push(Front->_right);
			
			if (Front == NULL)
			
				flag = true;
			
			else
			
				flag = false;
			
		
		if (flag == false)
		
			return false;
		
		else
		
			return true;
		
	


(在这会出现bug,具体的问题出现紧跟着提出)

<strong style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:18px;">这样写,会有一种情况出现误判,解释如下:</span></strong>


第一次出现NULL节点后,将flag置为true,后面遇到一个非空节点再将flag置为false,此时队列不为空,继续出队列,遇到NULL节点将flag置为true,此时队列为空,出循环,很明显,这个时候得到的结果就是错误的。

所以为了解决这种情况的误判,我们必须做以标记,在第一次出现NULL节点时并且后面紧跟着有非空节点出现时,直接返回,没有再进行判断的必要了。修改后代码如下:

bool _IsCompleteTree(Node* root)
	
		if (root == NULL)
		
			return true;
		
		if (root->_left == NULL&&root->_right == NULL)
		
			return true;
		
		queue<Node*> q;
		bool flag = false;
		int count = 0;
		q.push(root);
		while (!q.empty())
		
			Node* Front = q.front();
			q.pop();
			if (Front != NULL && (Front->_left||Front->_right))
			
                           q.push(Front->_left);
			   q.push(Front->_right);
			
			if (Front== NULL)
			
				flag = true;
				count++;
			
			else
			
				if (count == 1)
				
					flag = false;
					return flag;
				
				else
				
					flag = false;
				
				
			
		
		if (flag == false)
		
			return false;
		
		else
		
			return true;
		
	


<strong style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:18px;">测试用例可以多给以下几组:</span></strong>

int array[] = 1, 2, 3, '#', '#', 4, '#','#',5,6,'#','#',7,'#',8 ;//无左孩子,有右孩子
int array[] = 1, 2, 3, 8, '#', '#', '#', 4, '#', '#', 5, 6, '#', '#', 7 ;//最下面一层有一个孩子,且是左孩子
array[] = 1, 2, 3, '#', 9, 4, '#', '#', 5, 6, '#', '#', 7, '#', '#' ;//最下面一层有一个孩子,且是右孩子
int array[] = 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#', 7, '#', '#' ;//最下面一层全部是叶子节点
int array[] = 1, 2, 3, 8, '#', '#','#', 4,9, '#', '#','#', 5, 6, '#', '#', 7 ;//上迎面解释的这种情况
int array[] = 1 ;//只有一个根节点

int array[] = NULL;//空树


以上是关于判断一棵二叉树是否为完全二叉树的主要内容,如果未能解决你的问题,请参考以下文章

判断一棵二叉树是否为完全二叉树

判断一棵二叉树是否为完全二叉树

如何判断一棵二叉树是完全二叉树

判断一棵树是否是完全二叉树

二叉树

1110 Complete Binary Tree (25分) 判断一棵二插树是否是完全二叉树