判断一棵二叉查找树是否是平衡树

来源:互联网 发布:cf无后坐力软件 编辑:程序博客网 时间:2024/05/20 14:23

      首先平衡树的定义是,若一棵二叉查找树中任意一个结点的左右子树的深度差不超过1,则该树是平衡的。

法一:在遍历树的过程中,对每个结点的左右子树调用求深度TreeDepth。

结点的结构体:
struct TreeNode;typedef struct TreeNode *Position;typedef struct TreeNode *SearchTree;typedef int ElementType;struct TreeNode{ElementType Data;SearchTree Left;SearchTree Right;};

求树的深度:
int TreeDepth(SearchTree T){if (T == NULL)return 0;else{int Left = TreeDepth(T->Left);int Right = TreeDepth(T->Right);return Left > Right ? (Left + 1) : (Right + 1);}}

判 AVL:
bool isAVLTree_1(SearchTree T){if (T == NULL)return true;else{int left = TreeDepth(T->Left);int right = TreeDepth(T->Right);int diff = left - right;if (diff > 1 || diff < -1)return false;}return isAVLTree_1(T->Left) && isAVLTree_1(T->Right);}

      分析:虽然使用上述方法简单易懂,但是一个结点会被重复遍历多次,导致效率低。以下图为例,首先判断根节点是否是平衡时要访问5,6结点,然后在判断3是否是平衡时也要访问5,6。显然,重复遍历一个结点会直接影响性能。


法二:用后序遍历的方式遍历每一个结点

      使用后序遍历时,在遍历到一个结点之前已经遍历了它的左右子树,所以只要在遍历每个结点时记录它的深度,就可以一边遍历一边判断每个结点是不是平衡的。
bool isAVLTree_2(SearchTree T, int* depth){if (T == NULL){*depth = 0;return true;}int left, right;if (isAVLTree_2(T->Left, &left) && isAVLTree_2(T->Right, &right)){int diff = left - right;if (diff <= 1 && diff >= -1){*depth = 1 + (left > right ? left : right);return true;}}return false;}bool isAVLTree_2(SearchTree T){int depth = 0;return isAVLTree_2(T, &depth);}



0 0