二叉树的深度
对于二叉树的深度的求解,利用递归的方式求解很简单:
下面就来设计这个递归算法:
要求一个节点的高度,先求左子树的高度,然后再求解右子树的高度。 最后树的高度就是1+max(left_depth, right_depth)。 int leftLen = depth_tree(root->left); int rightLen = depth_tree(root->right); return 1 + max(leftLen, rightLen); 那么这个递归的出口是什么: (1)可以递归到1,如果一个节点不为NULL,但是这个节点的左子树为NULL, 并且右子树也为NULL,那么返回高度为1。 但是有这种情况:这个节点的左子树不为NULL,右子树为NULL,上面求leftLen和rightLen的递归还是会传入NULL。 所以这种递归的出口不可行。 (2)索性让递归的出口变成传入NULL参数,也就是说为NULL单独递归一次函数。 if(root == NULL) return 0; 就这一个出口就能解决所有的。
算法代码实现:
int depth_tree(TreeNode *root) { if(NULL == root) { return 0; } int nLeft = depth_tree(root->left); int nRight = depth_tree(root->right); return 1 + (nLeft > nRight ? nLeft : nRight); }
二叉树平衡的判定
还是用递归的想法,想判定根节点是不是平衡的,如果不是就直接返回false,如果是然后就分别去判断这个根的左子树和右子树是否都是平衡的二叉树。
代码实现:
bool IsBalance(TreeNode *root) { if(NULL == root) return true; int left = depth_tree(root->left); int right = depth_tree(root->right); if(abs(left-right) > 1) { return false; } return IsBalance(root->left) && IsBalance(root->right); }
但是现在算法的效率还是不够高,求解root的平衡性的时候,我们遍历了左子树和右子树求解子树的高度。当我们求解root孩子的平衡性的时候,还要求解root孩子左右子树的高度,有很大一部分节点重复的被遍历了。所以效率大大的降低了。
判定二叉树平衡的高效算法
前面的算法是,对于每一个节点都要去求解它的左右子树的高度,那么可以利用二叉树的后序遍历方式,当遍历到某个节点的时候,它的左子树和右子树都已经遍历完成,同时要分别带回左、右子树的高度,以便左右子树高度对比。
bool isBalance(TreeNode *root, int *depth) { if(root == NULL) { *depth = 0; return true; } int left, right; if(isBalance(root->left, &left) && isBalance(root->right, &right)) { int diff = left - right; if(diff >= -1 && diff <=1) { *depth = 1 + max(left, right); return true; } } return false; }
这里只是一个后序遍历带回高度的算法,每个节点仅仅的遍历了一次。
时间: 2024-10-10 07:22:26