完全二叉树的判定

完全二叉树的判定问题

1、完全二叉树
【描述1】
:一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。(百度百科上的定义)
【描述2】:一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下一层的叶结点集中在靠左的若干位置上(这是上课老师描述的方式)

2、代码实现

//二叉树定义
typedef struct btnode {
	char element;	//二叉树的值
	struct btnode *lchild;		//左孩子
	struct btnode *rchild;		//右孩子
}BTNode;
typedef struct bt {
	BTNode *root;
}BT;
//队列定义
typedef struct queue {
	char element;	//队列元素值
	BTNode* q;		//元素在二叉树中的地址
}Queue; 

//函数定义
void PreMakeTree(BT* bt);
btnode* CreatBTree(btnode *r);//以深度优先构造二叉树
void outPut(BT* bt);//输入二叉树
void PreOutPut(BTNode* r);
void isQTree(BT* tree); //判断是否是完全二叉树
//主函数
void main()
{

	BT tree;
	PreMakeTree(&tree);
	isQTree(&tree);
}
//以深度优先构造二叉树
btnode* CreatBTree(btnode *r)
{
	char in;
	in = getchar();
	if (in == '#')
		r = NULL;
	else
	{
		r = (btnode*)malloc(sizeof(btnode));
		r->element = in;
		r->lchild = CreatBTree(r->lchild);//构造左子树
		r->rchild = CreatBTree(r->rchild);//构造右子树
	}
	return r;
}
void PreMakeTree(BT* bt)
{
	printf("以深度优先生成树:");
	bt->root = CreatBTree(bt->root); 
}

//判断是否是完全二叉树
void isQTree(BT *tree)
{
	vector<char> ans;
	int i = 0;
	printf("**************************************");
	printf("\n");
	int NUM = 0;//队列中元素的个数
	int front = -1;//队列头
	int tail = -1;
	Queue *Q;
	Q = (Queue*)malloc(sizeof(Queue) * 20);
	if (!tree->root)	return;
	
	tail = tail + 1;
	Q[front].element = tree->root->element;
	Q[front].q= tree->root;
	NUM++;	
	//从队列中取元素
	while (NUM)
	{
		//从队列取出一个元素输出
		//printf("%c", Q[front].element);
		ans.push_back(Q[front].element);;//将宽度遍历的结果存入ans
		NUM--;
		if (!Q[front].q) {
			front = front + 1;
			continue;
		}
		int temp = front;
		//将孩子结点入队
		if (Q[temp].q->lchild)	//左孩子入队
		{
			BTNode* p = Q[temp].q->lchild;
			tail = tail + 1;
			Q[tail].element = p->element;
			Q[tail].q = p;
			NUM++;
		}
		if (Q[temp].q->rchild) //右孩子入队
		{
			BTNode* p = Q[temp].q->rchild;
			tail = tail + 1;
			Q[tail].element = p->element;
			Q[tail].q = p;
			NUM++;
		}
		if (!Q[temp].q->lchild)//没有左孩子
		{
				tail = tail + 1;
				Q[tail].element = '*';
				Q[tail].q = NULL;
				NUM++;
		}
		if (!Q[temp].q->rchild)//没有右孩子
		{
				tail = tail + 1;
				Q[tail].element = '*';
				Q[tail].q = NULL;
				NUM++;
		}

		front = front + 1;
	}
	int flag = 0;
	for (int i = 0; i < ans.size(); i++)
	{
		if (ans[i] == '*')
		{
			flag = i;
			break;
		}
	}
	for (int i = flag; i < ans.size(); i++)
	{
		if (ans[i] != '*')
		{
			printf("结果:不是完全二叉树");
			return ;
		}
	}
	printf("结果:是完全二叉树");
	return;
}

3、测试用例
测试用例1:
程序运行结果:
测试用例2:
运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值