- 平衡二叉树
- 简介
- 判断的必要条件
- 题目实例
- 代码实现
平衡二叉树 简介
判断的必要条件AVL树的名字来源于它的发明作者G.M. Adelson-Velsky 和 E.M. Landis。AVL树是最先发明的自平衡二叉查找树(Self-Balancing Binary Search Tree,简称平衡二叉树)。
平衡二叉树定义(AVL):它或者是一颗空树,或者具有以下性质的二叉排序树:它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。
- 平衡二叉树一定是二叉搜索树
- 平衡二叉树的左右子树的高度差不超过1
代码实现二叉树的平衡性:
利用二叉树遍历的思想,编写一个判断二叉树是否是一棵平衡二叉树的算法。
输入:第一行输入n,表示有n个数组元素,第二行输入二叉树的拓展前序遍历数组,空结点用0表示
输出:true或false
样例输入1:
11
50 45 46 0 0 0 65 0 70 0 0
样例输出1:false
样例输入2:
11
50 45 45 0 0 0 65 0 70 0 0
样例输出2:true
#includeusing namespace std; typedef struct node //二叉树结构定义 { int data; struct node* left, * right; }BiNode,*BiTree; void CreateTree(BiTree& root, int arr[],int n); //生成二叉树 void PreOrder(BiTree root); //判断是否为搜索二叉树 int height(BiTree root); //判断左右子树高度 int flag = 0; //用于标记左右子树的最大高度差 int flag1 = 0, flag2 = 0; //用于标记二叉树的左右节点是否符合搜索二叉树的定义 int i = 0; //用于标记生成二叉树途中数组元素的位置 int main() { int n, arr[1000]; cin >> n; for (int i = 0; i < n; i++) cin >> arr[i]; //获取数组元素 BiTree root = NULL, p = NULL; CreateTree(root, arr, i); //先序序列数组转为二叉树 PreOrder(root); //先序遍历中判断是否符合搜索二叉树 if (flag1 == 0&&flag2==0) //二者均为0说明符合搜索二叉树 { height(root); //判断任意节点左右子树高度差是否小于等于1,小于则是AVL if (flag <= 1) cout << "true"; else cout << "false"; } else cout << "flase"; return 0; } void CreateTree(BiTree& root, int arr[],int n) //将数组转为二叉树 { if (i >= n) //数组元素转化完毕,所有递归都开始退出 return; if (arr[i] == 0) { i++; return; } root = new BiNode; root->left = root->right = NULL; root->data = arr[i++]; CreateTree(root->left, arr,n); //录入左子树 CreateTree(root->right, arr,n); //录入右子树 } //用先序遍历来判断是否符合搜索二叉树定义 //即左节点小于父节点,右节点大于父节点 void PreOrder(BiTree root) { if (root == NULL) //遇见空节点退出 return ; if (root->left != NULL) //左节点不为空进进去判断与父节点大小关系 { if (root->left->data > root->data) //如果左节点大于父节点,说明不符合搜索二叉树定义,因此将flag1标记为1 { //表明不是AVL树 flag1 = 1; } } if (root->right != NULL) //同理,判断右节点与父节点关系 { if (root->right->data < root->data) //如果右节点小于父节点,违反搜索二叉树定义,flag2标记为1 { //表明不是AVL树 flag2 = 1; } } PreOrder(root->left); //递归判断左子树 PreOrder(root->right); //递归判断右子树 } //随便取名了,用来求树高,同时判断节点的左右子树的高度差 int height(BiTree root) { if (root == NULL) //空结点的高度为0 { return 0; } int h1 = height(root->left) + 1; //左子树高度加1即是从左子树往上数的本层高度 int h2 = height(root->right) + 1; //右子树高度加1即是右子树往上数的本层高度 if (h1 > h2) { flag = flag > h1 - h2 ? flag : h1 - h2; } else { flag = flag > h2 - h1 ? flag : h2 - h1; } return h1 > h2 ? h1 : h2; //左右子树高度+1后更大的才是本层的高度 }



