完全二叉树的判定问题
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:
运行结果: