完全二叉树的判断

完全二叉树也就是没有满的满二叉树,它的节点在每一层一定是连续分布的。如果出现哪一层中两个非空节点间隔一个空节点,那一定不是完全二叉树。如下图所示:

完全二叉树的判断_第1张图片

 

 算法思想:

由于完全二叉树在每一层非空节点都是一个接一个连续分布的,不可能出现两个非空节点之间交叉一个空节点,因此:可以通过层序遍历从上往下,从左往右将每一个节点(包括非空节点)都放到队列里,在出队列的过程中,如果遇到空节点,判断队列中剩下的元素是否有非空节点,若有非空节点则该树不是完全二叉树;若全是空节点,则该树为完全二叉树。 

代码实现:

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include 
#include 
#include 
#include 

#define MAXSIZE 20

typedef char DataType;

//二叉树结构体
typedef struct tree
{
	DataType data;
	struct tree* lchild, * rchild;
}Tree,*BTree;
//循环队列结构体
typedef struct Queue
{
	BTree data[MAXSIZE];
	int front, tail;
}Queue;

//初始化队列
void InitQueue(Queue* myQueue)
{
	for (int i = 0; i < MAXSIZE; i++)
	{
		myQueue->data[i] = 0;
	}
	myQueue->front = myQueue->tail = 0;
}
//入队列
void PushQueue(Queue* myQueue, BTree data)
{
	//判断队列是否满
	if ((myQueue->tail + 1) % MAXSIZE == myQueue->front)
	{
		printf("队列已满不能入队!\n");
		exit(-1);
	}
	myQueue->data[myQueue->tail] = data;
	myQueue->tail = (myQueue->tail + 1) % MAXSIZE;
}
//判断队列是否为空
bool QueueIsEmpty(Queue* myQueue)
{
	if (myQueue->front == myQueue->tail)
		return true;
	else
		return false;
}
//出队列
void PopQueue(Queue* myQueue)
{
	//判断队列是否为空
	if (QueueIsEmpty(myQueue))
	{
		printf("队列已为空不能出队!\n");
		exit(-1);
	}
	myQueue->data[myQueue->front] = NULL;
	myQueue->front = (myQueue->front + 1) % MAXSIZE;
}
//取队头元素
BTree GetQueueFrontValue(Queue* myQueue)
{
	//判断队列是否为空
	if (QueueIsEmpty(myQueue))
	{
		printf("队列已为空不能出队!\n");
		exit(-1);
	}
	return myQueue->data[myQueue->front];
}
//创建二叉树
int flag = 0;
BTree CreateTree()
{
	BTree root = NULL;
	DataType temp = 0;
	DataType data;
	if (flag == 0)
	{
		printf("请输入一个根节点:");
		flag = 1;
	}
	scanf_s("%c", &data, 1);
	temp = getchar();
	if (data == '#')
		return NULL;
	else
	{
		root = (BTree)malloc(sizeof(Tree));
		if (root == NULL)
		{
			printf("为根节点申请空间失败!\n");
			exit(-1);
		}
		root->data = data;
		printf("请输入%c的左孩子:", root->data);
		root->lchild = CreateTree();
		printf("请输入%c的右孩子:", root->data);
		root->rchild = CreateTree();
	}
	return root;
}

bool IsCompleteTree(BTree root)
{
	Queue myQueue;
	if (root == NULL)
		return true;
	InitQueue(&myQueue);
	BTree temp = root;

	PushQueue(&myQueue, root);
	
	while (!(QueueIsEmpty(&myQueue)))
	{
		temp = GetQueueFrontValue(&myQueue);
		PopQueue(&myQueue);//队头元素出队
		if (temp != NULL)//若没遇到NULL结点,则该结点的左右孩子入队列,空孩子结点也入队列
		{
			PushQueue(&myQueue, temp->lchild);
			PushQueue(&myQueue, temp->rchild);
		}
		else
		{//若遇到空结点,则判断队列后续元素是否都为NULL,若直到队列为空时temp都为NULL,则该二叉树为完全二叉树,否则就不是完全二叉树
			while (!(QueueIsEmpty(&myQueue)))
			{
				temp = GetQueueFrontValue(&myQueue);
				PopQueue(&myQueue);
				if (temp != NULL)
				{
					return false;
				}
			}
		}
	}
	return true;
}


int main(void)
{
	BTree root;
	bool flag;
	root = CreateTree();
	
	flag = IsCompleteTree(root);
	if (flag == true)
	{
		printf("该二叉树是完全二叉树\n");
	}
	else
	{
		printf("该二叉树不是完全二叉树!\n");
	}

	system("pause");
	return EXIT_SUCCESS;
}

 运行截图:

完全二叉树的判断_第2张图片 

完全二叉树的判断_第3张图片 

 

 

你可能感兴趣的:(数据结构,算法)