平衡二叉树的定义:首先它是一棵二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1。
判断是不是二叉排序树,只要判断每个节点的值是否大于它的左孩子(如果存在)的值和是否小于它的右孩子(如果存在)的值。
关键是判断每个节点的左右子树的高度差。有两种方法,一种是自顶向下,从根结点开始判断它的左右子树的高度差,如果符合条件,再分递归判断它的左右子树。这样存在一个问题就是,有大量的子树被多次遍历,使得时间效率不高。
另一种方法就是使用后序遍历,即自低向上。从叶结点开始判断,一次向上递归,这样需要记录每个节点的深度,当下次使用时直接读取该节点的深度,而不用再去遍历。
#include <iostream>
#include "BinaryTree.h"
using namespace std;
bool IsBalanced(BinaryTreeNode *pRoot, int *pDepth)
{
if(pRoot == NULL)
{
*pDepth = 0;
return true;
}
//判断根结点是否大于它的左孩子的值
if(pRoot->m_pLeft != NULL)
{
if(pRoot->m_nValue < pRoot->m_pLeft->m_nValue)
return false;
}
//判断根结点是否小于它的右孩子的值
if(pRoot->m_pRight != NULL)
{
if(pRoot->m_nValue > pRoot->m_pRight->m_nValue)
return false;
}
int leftDepth = 0, rightDepth = 0; //记录左右子树的深度
if(IsBalanced(pRoot->m_pLeft, &leftDepth)
&& IsBalanced(pRoot->m_pRight, &rightDepth))
{
int diff = leftDepth - rightDepth; //判断左右子树高度差是否符合平衡条件
if(diff >= -1 && diff <= 1)
{
*pDepth = 1 + (leftDepth > rightDepth) ? leftDepth : rightDepth;
return true;
}
}
return false;
}
bool IsBalanced(BinaryTreeNode *pRoot)
{
int depth = 0;
return IsBalanced(pRoot, &depth);
}
// ====================测试代码====================
void Test(char* testName, BinaryTreeNode* pRoot, bool expected)
{
if(testName != NULL)
printf("%s begins:\n", testName);
printf("Solution1 begins: ");
if(IsBalanced(pRoot) == expected)
printf("Passed.\n");
else
printf("Failed.\n");
}
// 完全二叉树
// 4
// / \
// 2 6
// /\ / \
// 1 3 5 7
void Test1()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(6);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(1);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode6 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
ConnectTreeNodes(pNode1, pNode2, pNode3);
ConnectTreeNodes(pNode2, pNode4, pNode5);
ConnectTreeNodes(pNode3, pNode6, pNode7);
Test("Test1", pNode1, true);
DestroyTree(pNode1);
}
// 不是完全二叉树,但是平衡二叉树
// 1
// / \
// 2 3
// /\ \
// 4 5 6
// /
// 7
void Test2()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
ConnectTreeNodes(pNode1, pNode2, pNode3);
ConnectTreeNodes(pNode2, pNode4, pNode5);
ConnectTreeNodes(pNode3, NULL, pNode6);
ConnectTreeNodes(pNode5, pNode7, NULL);
Test("Test2", pNode1, true);
DestroyTree(pNode1);
}
// 不是平衡二叉树
// 1
// / \
// 2 3
// /\
// 4 5
// /
// 6
void Test3()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
ConnectTreeNodes(pNode1, pNode2, pNode3);
ConnectTreeNodes(pNode2, pNode4, pNode5);
ConnectTreeNodes(pNode5, pNode6, NULL);
Test("Test3", pNode1, false);
DestroyTree(pNode1);
}
// 1
// /
// 2
// /
// 3
// /
// 4
// /
// 5
void Test4()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
ConnectTreeNodes(pNode1, pNode2, NULL);
ConnectTreeNodes(pNode2, pNode3, NULL);
ConnectTreeNodes(pNode3, pNode4, NULL);
ConnectTreeNodes(pNode4, pNode5, NULL);
Test("Test4", pNode1, false);
DestroyTree(pNode1);
}
// 1
// \
// 2
// \
// 3
// \
// 4
// \
// 5
void Test5()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
ConnectTreeNodes(pNode1, NULL, pNode2);
ConnectTreeNodes(pNode2, NULL, pNode3);
ConnectTreeNodes(pNode3, NULL, pNode4);
ConnectTreeNodes(pNode4, NULL, pNode5);
Test("Test5", pNode1, false);
DestroyTree(pNode1);
}
// 树中只有1个结点
void Test6()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
Test("Test6", pNode1, true);
DestroyTree(pNode1);
}
// 树中没有结点
void Test7()
{
Test("Test7", NULL, true);
}
int main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
}