【c++学习笔记】判断一棵树是否为完全二叉树

题目描述:

通俗来讲,完全二叉树的特点:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部

 

输入格式和输出格式:

为完成这道作业题,首先我们要创建一棵树,这里我们先把树的元素储存在一个vector里面,然后采用逐层遍历的方法创建树:

typedef struct TreeNode{
    int val;
    TreeNode *left, *right;
    TreeNode(int v=0,TreeNode* l=NULL, TreeNode* r=NULL)
    {
        val = v;
        left=l;
        right=r;
    }
}TreeNode;

//树的每一个节点

TreeNode * createTree(vector<int> &v) {
	if (v.empty()) {
		return NULL;
	}
	//使用逐层遍历的方式,生成树
	queue<TreeNode*>q;
	TreeNode* root = new TreeNode(v[0]);
	q.push(root);
	int idx = 1;//用以表示当前数组可用的元素下标
	while (!q.empty()&&idx<v.size()) {   //如果q不为空(创建成功)且数组中还有元素,执行循环
		int cnt = q.size();
		for (int i = 1; i <= cnt; i++) {
			TreeNode* cur = q.front();
			q.pop();
			//判断左子树是否为空
			if (v[idx] != -1) {
				TreeNode* t = new TreeNode(v[idx]);
				cur->left = t;
				q.push(cur->left);
			}
			idx++;
			if (idx >= v.size()) {
				break;
			}
			//判断右子树是否为空
			if (v[idx] != -1) {
				TreeNode* t = new TreeNode(v[idx]);
				cur->right = t;
				q.push(cur->right);
			}
			idx++;
		}
	}
	return root;//返回生成的树的根节点
}

用递归的方式删除树:

void destroyTree(TreeNode* root)
{
	if(!root)
		return ;
	destroyTree(root->left);
	destroyTree(root->right);
	delete root;
}

判断是否为完全二叉树的函数(采用从根节点开始一个一个节点入队,并判断队列中节点是否满足定义的方法)(这是给出的标准答案,简洁明了):

bool isCompleteTree(TreeNode* root) {
        queue<TreeNode*>q;
        q.push(root);
        bool flag=false;
        while(!q.empty()){
            TreeNode* node =q.front();//每次取队首节点
            q.pop();
            if(node==NULL){//如果为空,说明有左儿子为空的情况出现,不是完全二叉树,用continue到下一层循环判断是否为最后一个节点
                flag=true;
                continue;
            }
            if(flag) return false;
            q.push(node->left);//该节点的左儿子入队
            q.push(node->right);//该节点的左儿子入队
            
        }
        return true;
    }

附上我当时写的:

bool isCompleteTree(TreeNode* root){
    if(root==NULL)
    return false;
    bool flag=false;//如果一个节点没有子节点;只要出现了空子树的节点,后面出现的必须为叶子节点
    bool result=true;
    queue<TreeNode*> q;
    q.push(root);
    while(!q.empty()){
        TreeNode* temp=q.front();
        q.pop();
        if(flag){
            if(temp->left!=NULL||temp->right!=NULL){
                result=false;
                break;
            }
        }
        else{
            if(temp->left!=NULL&&temp->right!=NULL){
                q.push(temp->left);
                q.push(temp->right);
            }
            else if(temp->left!=NULL&&temp->right==NULL){
                q.push(temp->left);
                flag=true;
            }
            else if(temp->left==NULL&&temp->right!=NULL){
                result=false;
                break;
            }
            else{
                flag=true;
            }
        }
    }
    return result;
}

main函数:

int main() {
    int num;
    cin >> num;
    vector<int>values(num);
    for(unsigned int i=0;i<num;i++)
        cin >> values[i];
    TreeNode* root = createTree(values);
    cout << isCompleteTree(root) << endl;
    destroyTree(root);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值