编程判断一个树是完全二叉树(使用层次遍历实现)

完全二叉树:一棵具有N个节点的二叉树的结构与满二叉树的前N个节点的结构相同

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

可以使用层序遍历,只需2个步骤

第一步:如果遍历到一个节点只有右子树没有左子树,则不是完全二叉树

第二部:如果遍历到一个节点只有左子树,那么后面遍历到的节点必须是叶子节点,否则也不是完全二叉树

排除以上两种情况,则树是完全二叉树

核心代码:

//层序遍历
int LayerOrder(BiTreeNode *head)
{
	bool flag=0;
	LQueue Q;
	Initiate_Queue(&Q);
	BiTreeNode *p;
	if(head!=NULL) AppendQueue(&Q,head);
	while(QueueNotEmpty(&Q))
	{
		if(flag)
		{
			if(p->LChild!=NULL || p->RChild!=NULL)
				return 0;
		}
		p=QueueDelete(&Q);
		if(p->LChild!=NULL) AppendQueue(&Q,p->LChild);
		if(p->RChild!=NULL) AppendQueue(&Q,p->RChild);
		if((p->LChild==NULL) && (p->RChild!=NULL)) return 0;  //如果左子树为空,右子树存在,则不是完全2叉树
        //如果左子树存在,右子树为空,设置flag为1,进行进一步判断,判断后面遍历的节点是否为叶子节点
		if(p->LChild!=NULL &&p->RChild==NULL) flag=1;
		//如果左子树,右子树都为空,设置flag为1,进行进一步判断,判断后面遍历的节点是否为叶子节点
		if(p->LChild==NULL && p->RChild==NULL) flag=1;

	}
	return 1;
}

完整代码如下:

#include<iostream>
using namespace std;

typedef struct biTreeNode
{
	char data;
	struct biTreeNode *LChild;
	struct biTreeNode *RChild;
}BiTreeNode;

void Initiate_Tree(BiTreeNode **head)
{
	(*head)=(BiTreeNode *)malloc(sizeof(BiTreeNode));
	(*head)->LChild=NULL;
	(*head)->RChild=NULL;
}

 BiTreeNode *InsertLChild(BiTreeNode *head,char x)
{
	if(head==NULL) return NULL;
	else
	{
	BiTreeNode *p1,*p2;
	p1=head->LChild;
	p2=(BiTreeNode*)malloc(sizeof(BiTreeNode));
	p2->data=x;
	p2->RChild=NULL;
	head->LChild=p2;
	p2->LChild=p1;
	return p2;
	}
}

BiTreeNode* InsertRChild(BiTreeNode *head,char x)
{
	if(head==NULL) return NULL;
	{
	BiTreeNode *p1,*p2;
	p1=head->RChild;
	p2=(BiTreeNode*)malloc(sizeof(BiTreeNode));
	p2->data=x;
	p2->LChild=NULL;
	head->RChild=p2;
	p2->RChild=p1;
	return p2;
	}
}

void DLR(BiTreeNode *head)
{
	if(head==NULL)  return;
	else
	{
	cout<<head->data<<"  ";
	DLR(head->LChild);
	DLR(head->RChild);
	}
}

//==================================================

typedef struct lNode
{
	BiTreeNode *data;
	struct lNode *next;
}LNode;

typedef struct lQueue
{
	LNode *front;
	LNode *rear;
}LQueue;

void Initiate_Queue(LQueue *Q)
{
	Q->front=NULL;
	Q->rear=NULL;
}

void AppendQueue(LQueue *Q,BiTreeNode *head)
{
	LNode *p1;
	p1=(LNode *)malloc(sizeof(LNode));
	p1->next=NULL;
	p1->data=head;
	if(Q->front==NULL)
	{
		Q->front=Q->rear=p1;
	}
	else
	{
		Q->rear->next=p1;
		Q->rear=p1;
	}
}

BiTreeNode * QueueDelete(LQueue *Q)
{
	if(Q->front==NULL) return NULL;
	else
	{
		BiTreeNode *p;
		p=Q->front->data;
		Q->front=Q->front->next;
		return p;
	}
}

int QueueNotEmpty(LQueue *Q)
{
	if(Q->front==NULL) return 0;
	else return 1;
}

//层序遍历
int LayerOrder(BiTreeNode *head)
{
	bool flag=0;
	LQueue Q;
	Initiate_Queue(&Q);
	BiTreeNode *p;
	if(head!=NULL) AppendQueue(&Q,head);
	while(QueueNotEmpty(&Q))
	{
		if(flag)
		{
			if(p->LChild!=NULL || p->RChild!=NULL)
				return 0;
		}
		p=QueueDelete(&Q);
		if(p->LChild!=NULL) AppendQueue(&Q,p->LChild);
		if(p->RChild!=NULL) AppendQueue(&Q,p->RChild);
		if((p->LChild==NULL) && (p->RChild!=NULL)) return 0;  //如果左子树为空,右子树存在,则不是完全2叉树
        //如果左子树存在,右子树为空,设置flag为1,进行进一步判断,判断后面遍历的节点是否为叶子节点
		if(p->LChild!=NULL &&p->RChild==NULL) flag=1;
		//如果左子树,右子树都为空,设置flag为1,进行进一步判断,判断后面遍历的节点是否为叶子节点
		if(p->LChild==NULL && p->RChild==NULL) flag=1;

	}
	return 1;
}

void main()
{
	BiTreeNode *head,*p,*p1;
	int flag;
	Initiate_Tree(&head);
	head->data='j';
	p=InsertLChild(head,'k');
	p=InsertLChild(p,'a');
	InsertRChild(head,'b');
	cout<<"前序遍历为:"<<endl;
	DLR(head);
	cout<<endl;
	flag=LayerOrder(head);
	if(flag)
		cout<<"是二叉树"<<endl;
	else
		cout<<"不是二叉树"<<endl;
	system("pause");
}
时间: 2024-11-04 04:06:59

编程判断一个树是完全二叉树(使用层次遍历实现)的相关文章

数据结构:树的BFS,树的层次遍历! 按先序遍历创建一棵树,然后以层次遍历输出。

按先序遍历创建一棵树,以层次遍历输出 样例输入 A B # D # # C E # # F # # 样例输出 LevelOrder: A B C D E F 代码: #include <iostream> #include <queue> using namespace std; struct node { //表示一个树上的节点 char ch; node *left, *right; }; node* creat() { //以递归的方式构造一棵二叉树 node *root =

判断一个数列是不是搜索二叉树后续遍历输出的结果

剑平面阿里被问到这个,刚开始画了下看有什么性质,乱蒙了几个都被推翻了,初始感觉就是要O(n)的,因为印象中BST的构树都可以O(nlogn)搞定.然后剑平说最后一个数肯定是根节点,一下反应过来了,就是二分出间隔点然后两边递归判断,不过这好像还是构树的思路,可以把整棵树构造出来.然后剑平说不是二分,直接遍历.不科学啊,明显的二分,然后去网上搜一下,都是遍历的,O(n^2)的吧.想了想,二分是当做合法的情况来构树的,不合法怎么判断?构造出搜索二叉树后中序遍历一下不就行了么,妥妥的O(nlogn)吧.

输入层次遍历,输出中序,前序,后序遍历

题目描述 输入完全二叉树的层次遍历序列,输出该完全二叉树的中序遍历序列. 例如下面二叉树的层次遍历序列为“ABCDE",中序遍历为"DBEAC". A /    \ B      C /    \ D     E 遍历数采用递归写法,无需多说:而且前,中,后,皆为一法: 重要的是看怎么建立一个二叉树,且听分解: //输入层次遍历输出中序 #include <cstdio>#include <cstdlib>#include <cstring>

设计一个算法,判断一个二叉树是否为完全二叉树

思想:根据完全二叉树的定义,对完全二叉树按照从上到下.从左到右的层次遍历,应该满足一下两条要求: ●某节点没有左孩子,则一定无右孩子 ●若某节点缺左或右孩子,则其所有后继一定无孩子 若不满足上述任何一条,均不为完全二叉树. 算法思路:采用层序遍历算法,用cm变量值表示迄今为止二叉树为完全二叉树(其初值为1,一旦发现不满足上述条件之一,则置cm为0),bj变量值表示迄今为止所有节点均有左右孩子(其初值为1),一旦发现一个节点没有左孩子或没有右孩子时置bj为0),在遍历完毕后返回cm的值. 对应的算

判断一个整数不是2的阶次方树

如果是一个2的阶次方,那么它的二进制数的首位一般是1,后面接若干个0.比如8就是1000,64是100 0000. 如果将这个数减1后,再与该数做和&运算,则改全为0. package cn.usst.DataTest; import java.io.*; /** * 从键盘输入一个值 */ public class InputData { static private String s = ""; static public void input() { BufferedRe

28、输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 思路:  1.当Tree1和Tree2都不为零的时候,才进行比较.否则直接返回false  2. 2.1如果找到了对应Tree2的根节点的点, 以这个根节点为为起点判断是否包含Tree2 2.2 如果找不到,那么就再去root的左孩子当作起点,去判断时候包含Tree22.3 如果还找不到,那么就再去root的右孩子当作起点,去判断时候包含Tree2 1 public class Solution

编程:判断一个点是否在三角形内部

题目描述: 在二维坐标系中,所有的值都是double类型,那么一个三角形可以由3个点来代表,给定3个点代表的三角形,再给定一个点(x, y),判断(x, y)是否在三角形中 题目分析: 方法1:面积法:如果点(x, y)在三角形内部,那么三个小三角形的面积相加等于大三角形面积. 注意:已知三角形三个点,求三角形面积. 方法2:向量法:如果点(x, y)在三角形内部,那么从某个点逆时针出发,点(x, y)都在每条边的左侧. 注意:判断一个点在一个有向边的左侧还是右侧. #include<iostr

(树)每一层节点的右指针问题(层次遍历)

题目:https://www.nowcoder.com/practice/fdbd05d647084fcf9be78444e231998b?tpId=46&tqId=29064&tPage=1&rp=1&ru=/ta/leetcode&qru=/ta/leetcode/question-ranking 题目翻译: 给定一个二叉树 struct TreeLinkNode { TreeLinkNode * left; TreeLinkNode * right; Tree

判断A树是否包含B树结构

题目:输入两棵二叉树A和B,判断B是不是A的子结构 分析:根据数的遍历方法,首先想到的是采用递归的方式要更简单些,树A从根节点进行遍历,首先判断与B的根节点值是否相等,如果相等则进行递归遍历验证,否则验证树A的其他节点,直到所有的结点遍历完. 注意的就是指针是否为NULL,因为自己编程能力不好,所以有些很简单的也做了注释,方便以后自己理解. //判断B是不是A的子树 struct BinaryTree{ int m_value; BinaryTree * LeftTree; BinaryTree