怎么判断是不是是完全二叉树 用C++或C语言

Posted

tags:

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

你可以上网先找一个用队列实现二叉树的广度优先搜索的代码,然后在代码中增加一个标志变量tag,初始化为0。然后找到代码中访问结点的那句代码,在那句代码处增加
if(tag==0)
判断该结点是否有两个孩子,如果没有两个孩子,则将tag=1
else
判断该结点是否为叶结点,如果不是叶结点,则不是完全二叉树。
参考技术A 广度优先搜索整个二叉树,一旦找一个节点只不含有子节点或者子含有一个左子节点,那么后续的所有节点都必须是叶子节点。否则,该树就不是完全二叉树。

实现的时候需要用到队列。

下面是程序:

#include <stdlib.h>
#include <stdio.h>
class TreeNode
public:
int value;
TreeNode *left;
TreeNode *right;
TreeNode(int v) : value(v)
left = NULL;
right = NULL;

~TreeNode()
if (left != NULL)
delete left;
left = NULL;

if (right != NULL)
delete right;
right = NULL;


;

struct QueueNode
TreeNode *data;
QueueNode *next;
;

//用链表的方式实现队列
class Queue
private:
QueueNode *head; //队列的投指针
QueueNode *tail; //队列的尾指针
public:
Queue()

head = NULL;
tail = NULL;

void enqueue(TreeNode *node) //入队列
QueueNode *q = new QueueNode();
q->data = node;
q->next = NULL;
if(head == NULL)
head = q;
tail = q;
else
tail->next = q;
tail = q;


//判断队列是否是空
bool isEmpty()
return head == NULL;

//出队列
TreeNode * dequeue()
if(head == NULL) return NULL; //如果当前队列是空,直接返回null.
QueueNode *p = head;
TreeNode *ptree = p->data;
head = head->next;
if (head==NULL) //如果出队列之后,队列为空了,则修改tail为空
tail == NULL;

p->next = NULL;
delete p; //删除队列节点
return ptree;

~Queue()
QueueNode *p = head, *q;
while(p != NULL)
q = p;
p = p->next;
delete q;


;
/*
判断一个二叉树是否是完全二叉树
广度优先搜索整个二叉树,一旦找一个节点只不含有子节点或者子含有一个左子节点,
那么后续的所有节点都必须是叶子节点。否则,该树就不是完全二叉树。
*/
bool isCompBinTree(TreeNode *root)


if(root == NULL) return true;
Queue qu;
bool last = false; //判断当前是否已经找到了第一个不含有两个子节点的节点。
bool isCompBTree = true;
TreeNode *p;
qu.enqueue(root);
while( ! qu.isEmpty())
p = qu.dequeue();
if(! last) //前面所有的节点都含有两个子节点
if (p->left != NULL && p->right !=NULL) //当前节点也含有两个子节点
qu.enqueue(p->left);
qu.enqueue(p->right);
else if (p->left != NULL && p->right==NULL) //当前节点只含有左子节点,则在其后面的所有节点都必须是叶子节点
last = true;
qu.enqueue(p->left);
else if (p->left == NULL && p->right!=NULL) //当前节点只含有右子节点,该树不是完全的。
last = true;
isCompBTree = false;
break;
else //当前节点不含有任何的子节点。
last = true;


else

//已经找到了第一个不含有两个子节点的节点,当前扫描的节点必须是叶子节点。
if ( p->left!=NULL || p->right != NULL)
isCompBTree = false;
break;



if (isCompBTree)
printf("是完全二叉树.\n");
else
printf("不是完全二叉树.\n");

return isCompBTree;

/*
1 1
2 3 2 3
4 5 4 5 6

*/
void clear(TreeNode *ele[], int n)
for(int i=0; i<n; i++)
ele[i]->left = NULL;
ele[i]->right = NULL;


int main()

TreeNode *ele[10];
TreeNode *root, *p, *q;
for(int i=0; i<10; i++)
ele[i] = new TreeNode(i+1);


printf("Case 1: ");
root = ele[0];
root->left = ele[1]; root->right=ele[2];
root->left->left=ele[3]; root->left->right=ele[4];
isCompBinTree(root);

printf("Case 2: ");
clear(ele, 10);
root = ele[0];
root->left = ele[1]; root->right=ele[2];
root->left->right=ele[3]; root->right->left=ele[4]; root->right->right=ele[5];
isCompBinTree(root);

/*
1
*/
printf("Case 3: ");
clear(ele, 10);
root = ele[0];
isCompBinTree(root);

/*
1
2
3
*/
printf("Case 4: ");
clear(ele, 10);
root = ele[0];
root->left = ele[1];
root->left->left = ele[2];
isCompBinTree(root);

/*
1
2
*/
printf("Case 5: ");
clear(ele, 10);
root = ele[0];
root->left = ele[1];
isCompBinTree(root);

/*
1
2 3
4 5
*/
printf("Case 6: ");
clear(ele, 10);
root = ele[0];
root->left = ele[1]; root->right=ele[2];
root->right->left = ele[3]; root->right->right = ele[4];
isCompBinTree(root);

clear(ele, 10);
for(int i=0; i<10; i++)
delete ele[i];

system("pause");
return 0;

2021-04-11:判断二叉树是否是完全二叉树?

2021-04-11:判断二叉树是否是完全二叉树?


福大大 答案2021-04-11:


按层遍历。


代码用golang编写。代码如下:

package main
import ( "container/list" "fmt")
func main() { head := &TreeNode{Val: 1} head.Left = &TreeNode{Val: 2} head.Right = &TreeNode{Val: 3} head.Left.Left = &TreeNode{Val: 4} //head.Right.Right = &TreeNode{Val: 5} ret := isCBT1(head) fmt.Println(ret)}
//Definition for a binary tree node.type TreeNode struct { Val int Left *TreeNode Right *TreeNode}
func isCBT1(head *TreeNode) bool { if head == nil { return true } queue := list.New() // 是否遇到过左右两个孩子不双全的节点 leaf := false var l *TreeNode var r *TreeNode queue.PushBack(head) for !(queue.Len() == 0) { head = queue.Remove(queue.Front()).(*TreeNode) l = head.Left r = head.Right if // 如果遇到了不双全的节点之后,又发现当前节点不是叶节点 (leaf && (l != nil || r != nil)) || (l == nil && r != nil) { return false } if l != nil { queue.PushBack(l) } if r != nil { queue.PushBack(r) } if l == nil || r == nil { leaf = true } } return true}

执行结果如下:

***

[左神java代码](https://github.com/algorithmzuo/algorithmbasic2020/blob/master/src/class12/Code01_IsCBT.java)

[评论](https://user.qzone.qq.com/3182319461/blog/1618097666)


以上是关于怎么判断是不是是完全二叉树 用C++或C语言的主要内容,如果未能解决你的问题,请参考以下文章

常见数据结构——完全二叉树(定义特征节点个数的判断以及C++简单实现)

每日一道面试题-完全二叉树的判断

已知一颗二叉链表表示二叉树T ,编写函数,判断T是不是为完全二叉树。先

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

二叉树oj ----->判断二叉树是否为完全二叉树

数据结构复习笔记——二叉树的常用接口的实现(c语言)