完全二叉树的一些知识

完全二叉树就是在满二叉树的基础上从右往左去若干节点。

判断是否为完全二叉树有两个判断条件,

1.如果左节点为空,而右节点不为空,那么不是完全二叉树。
2.如果层序遍历已经发现了左节点不为空而右节点为空的节点,那么接下来遍历的必须全是叶子节点,否则不是完全二叉树。

满足以上条件就是完全二叉树。(默认空节点也是完全二叉树)

class Solution {
public:
    bool isCompleteTree(TreeNode* root) {
        bool ok=true;
        queue<TreeNode*>p;
        p.push(root);
        while(p.size())
        {
            auto t=p.front();
            p.pop();
            if((!t->left&&t->right)||(!ok&&(t->left||t->right)))
            {
                return false;
            }
            if(t->left)p.push(t->left);
            if(t->right)p.push(t->right);
            if(!t->left||!t->right)
            {
                ok=false;
            }
        }
        return true;
    }
};

O(logn)计算完全二叉树的节点个数

准备一个函数,功能是计算一个树的最大高度,也是一直取非空节点的左节点,同时记录次数即可。

如果一个树的右子树的高度等于大树的高度,说明左子树是满的,那么只需计算右子树。

如果不等于,说明右子树没到最后一层,而是在倒数第二层是满的,那么只需计算左子树。

public static int countNodes(TreeNode head) {
		if (head == null) {
			return 0;
		}
		return f(head, 1, mostLeft(head, 1));
	}

	// cur : 当前来到的节点
	// level :  当前来到的节点在第几层
	// h : 整棵树的高度,不是cur这棵子树的高度
	// 求 : cur这棵子树上有多少节点
	public static int f(TreeNode cur, int level, int h) {
		if (level == h) {
			return 1;
		}
		if (mostLeft(cur.right, level + 1) == h) {
			// cur右树上的最左节点,扎到了最深层
			return (1 << (h - level)) + f(cur.right, level + 1, h);
		} else {
			// cur右树上的最左节点,没扎到最深层
			return (1 << (h - level - 1)) + f(cur.left, level + 1, h);
		}
	}

	// 当前节点是cur,并且它在level层
	// 返回从cur开始不停往左,能扎到几层
	public static int mostLeft(TreeNode cur, int level) {
		while (cur != null) {
			level++;
			cur = cur.left;
		}
		return level - 1;
	}
posted @ 2026-03-03 13:45  Lambda_L  阅读(4)  评论(0)    收藏  举报