Balance Binary Tree
是一种二叉排序树,其中每个节点的左子树跟右子树的高度至多为1;因为发现解决平衡二叉树算法的两个人名字命名为AVL树;我们将二叉树节点的左子树深度减去右子树深度的值(Hleft-Hright)=>平衡因子BF(Balance Factor) -1,0,1; 平衡的引入就是为了最大化实现查找为O(logN)
距离插入节点距离最近,且平衡因子的绝对值大于1的节点为根的子树,我们称为最小不平衡子树。
BBT 实现原理就是在构造二叉排序树时,每当插入一个节点时,先检查是否因插入而破坏了树的平衡性。若是则找到最小不平衡子树,调制最小不平衡子树的链接关系,进行相应旋转,成为新的平衡子树。
- typedef struct tree_node
- {
- int data;
- int bf;//Balance Factor 平衡因子
- struct tree_node* left;
- struct tree_node* right;
- }TREE_NODE;
不平衡可能出现4种
1.LL左左
其中D是新插入的节点,红色节点K2是失去平衡的节点。需要对K1和K2进行左旋调整即将K1作为根,将K2作为K1的左子树,K1的右子树调整为K2的左子树。如下图所示
进行左旋变换
- //左边高L
- void SingleRotateWithLeft(TREE_NODE** root)
- {
- TREE_NODE* temp;
- temp =(*root)->left;
- (*root)->left = temp->right;
- temp->right = *root;
- *root = temp;
- }
先对K1和K2进行右旋,然后再对K3和K2进行左旋,最终实现平衡。如下图所示
一次右旋转->一次左旋
- //左边过高LR
- void DoubleRotateWithLeft(TREE_NODE** root)
- {
- SingleRotateWithRight(&(*root)->left);
- SingleRotateWithLeft(root);
- }
3.RR右右
将K2的右子树更改为K1的左子树,K1的左子树更改为K2即完成的右旋,如下图所示
一次右旋
- //右边高的时L
- void SingleRotateWithRight(TREE_NODE** root)
- {
- TREE_NODE* temp;
- temp = (*root)->right;
- (*root)->right = temp->left;
- temp->left = *root;
- *root = temp;
- }
4.RL右左
右左双旋:先对K1和K2进行左旋,然后在对K2和K3进行右旋,最终实现平衡。如下图所示
上面是AVL树四种旋转情况,下面来实现一下AVL树。AVL树的实现跟上一章讲的二叉查找树相似,区别在于在插入和删除节点是需要对树进行调整以满足平衡条件
- #include "Queue.h"
- #include <iostream>
- using namespace std;
- #include <vector>
- typedef struct avlnode
- {
- int key;
- int height;
- struct avlnode* left;
- struct avlnode* right;
- }AVLNode;
- typedef struct avltree
- {
- AVLNode* root;
- }AVLTree;
- typedef struct stack
- {
- AVLNode* base; //在栈构造前和销毁后,base的值为NULL
- AVLNode* top; //栈顶指针
- int StackSize; //当前已分配的存储空间,以元素为单位
- }Stack;
- AVLTree* CreateAVLTree()
- {
- AVLTree* tree = new AVLTree;
- tree->root = NULL;
- return tree;
- }
- int RootHeight(const AVLNode* root)
- {
- if(root)
- {
- return root->height;
- }
- else
- {
- return 0;
- }
- }
- int Max(const int& a, const int& b)
- {
- return a > b ? a : b;
- }
- /*
- 100 85
- / \ 右旋 / \
- 85 120 ------ -> 60 100
- / \ \ / \
- 60 90 80 90 120
- \
- 80
- */
- void SingleRotateWithLeft(AVLNode* &root)
- {
- AVLNode* temp;
- temp =root->left;
- root->left = temp->right;
- temp->right = root;
- root->height = Max(RootHeight(root->left), RootHeight(root->right))+1;
- temp->height = Max(RootHeight(temp->left), RootHeight(temp->right))+1;
- root = temp;
- }
- /*
- 80 90
- / \ 左旋 / \
- 60 90 ---- -> 80 120
- / \ / \ /
- 85 120 60 85 100
- /
- 100
- */
- void SingleRotateWithRight(AVLNode* & root)
- {
- AVLNode* temp;
- temp =root->right;
- root->right = temp->left;
- temp->left = root;
- root->height = Max(RootHeight(root->left), RootHeight(root->right))+1;
- temp->height = Max(RootHeight(temp->left), RootHeight(temp->right))+1;
- root = temp;
- }
- /*
- 100 100 90
- / \ 左旋 / \ 右旋 / \
- 80 120 ------> 90 120 ------> 80 100
- / \ / / \ \
- 60 90 80 60 85 120
- / / \
- 85 60 85
- */
- void DoubleRotateWithLeft(AVLNode* & root)
- {
- SingleRotateWithRight(root->left);
- SingleRotateWithLeft(root);
- }
- /*
- 80 80 85
- / \ 右 旋 / \ 左 旋 / \
- 60 100 ------> 60 85 -------> 80 100
- / \ \ / / \
- 85 120 100 60 90 120
- \ / \
- 90 90 120
- */
- void DoubleRotateWithRight(AVLNode*& root)
- {
- SingleRotateWithLeft(root->right);
- SingleRotateWithRight(root);
- }
- AVLNode* FindNode(int data, AVLNode* root) //FindNode
- {
- if(NULL == root)
- {
- return NULL;
- }
- else if(data < root->key)
- {
- return FindNode(data, root->left);
- }
- else if(data > root->key)
- {
- return FindNode(data, root->right);
- }
- else
- {
- return root;
- }
- }
- AVLNode* FindMin(AVLNode* root) //FindMin
- {
- if(NULL == root)
- {
- return NULL;
- }
- else if( NULL== root->left)
- {
- return root;
- }
- else return FindMin(root->left);
- }
- AVLNode* FindMax(AVLNode* root) //FindMax
- {
- if(NULL == root)
- {
- return NULL;
- }
- else if( NULL== root->right)
- {
- return root;
- }
- else return FindMax(root->right);
- }
- bool AVLInsert(AVLNode* &root, int data)
- {
- if(NULL == root)
- {
- root = new AVLNode;
- if(NULL == root)
- {
- return false;
- }
- root->key = data;
- root->height = 0;
- root->left = NULL;
- root->right = NULL;
- }
- else if(NULL != FindNode(data,root))
- {
- cout<<data<<" has been insert ! ";
- }
- else if(data < root->key)
- {
- AVLInsert(root->left, data);
- if(2 == RootHeight(root->left) - RootHeight(root->right))
- {
- if(data < root->left->key)
- {
- SingleRotateWithLeft(root);
- }
- else
- {
- DoubleRotateWithLeft(root);
- }
- }
- }
- else if(data > root->key)
- {
- AVLInsert(root->right, data);
- if(2 == RootHeight(root->right) - RootHeight(root->left))
- {
- if(data > root->right->key)
- {
- SingleRotateWithRight(root);
- }
- else
- {
- DoubleRotateWithRight(root);
- }
- }
- }
- root->height = Max(RootHeight(root->left), RootHeight(root->right))+1;
- return true;
- }
- bool AVLDelete(AVLNode* &root, int data) // 删除
- {
- AVLNode* temp;
- if(NULL == root)
- {
- return false;
- }
- else if(data < root->key)
- {
- AVLDelete(root->left, data);
- }
- else if(data > root->key)
- {
- AVLDelete(root->right, data);
- }
- else
- {
- if((root->left != NULL) && (root->right != NULL))
- {
- temp = FindMin(root->right); //右边找最小值
- root->key = temp->key; //将找到的值赋给当前root
- AVLDelete(root->right, root->key); //删除在右边找到的值
- }
- else
- {
- temp = root;
- if(NULL == root->left )
- {
- root = root->right;
- }
- else if(NULL == root->right)
- {
- root = root->left;
- }
- delete temp;
- temp = NULL;
- }
- return true;
- }
- }
- int TotalNodeNum(AVLNode* root) //节点总数
- {
- if(root)
- {
- int LNodeNum = TotalNodeNum(root->left);
- int RNodeNum = TotalNodeNum(root->right);
- return LNodeNum + RNodeNum +1;
- }
- return 0;
- }
- int LeafNodeNum(AVLNode* root)//叶子节点数
- {
- int leaf = 0;
- int LNodeNum = 0;
- int RNodeNum = 0;
- if(root)
- {
- if(NULL==root->left && NULL == root->right)
- {
- leaf =1;
- }
- else
- {
- LNodeNum = LeafNodeNum(root->left);
- RNodeNum = LeafNodeNum(root->right);
- leaf = LNodeNum + RNodeNum;
- }
- }
- else
- {
- return 0;
- }
- return leaf;
- }
- int RootDepth(AVLNode* root)//这个节点的深度
- {
- if(root)
- {
- int LHigh = RootDepth(root->left);
- int RHigh = RootDepth(root->right);
- return LHigh > RHigh ? LHigh+1 : RHigh+1;
- }
- return 0;
- }
- void SwapRootLeftRight(AVLNode * root)//实现交换每个节点的左右节点
- {
- AVLNode* temp;
- if(root)
- {
- temp = root->left;
- root->left = root->right;
- root->right = temp;
- SwapRootLeftRight(root->left);
- SwapRootLeftRight(root->right);
- }
- }
- void PreOrderTraverse(const AVLNode* root)
- {
- if(root)
- {
- cout << root->key << " ";
- PreOrderTraverse(root->left);
- PreOrderTraverse(root->right);
- }
- }
- void InOrderTraverse(const AVLNode* root)
- {
- if(root)
- {
- InOrderTraverse(root->left);
- cout << root->key << " ";
- InOrderTraverse(root->right);
- }
- }
- void PostOrderTraverse(const AVLNode* root)
- {
- if(root)
- {
- PostOrderTraverse(root->left);
- PostOrderTraverse(root->right);
- cout << root->key << " ";
- }
- }
- void LevelTraverse( AVLNode* root)
- {
- if(NULL == root)
- {
- return;
- }
- vector<AVLNode*>vec;
- vec.push_back(root);
- int cur = 0;
- while(cur < vec.size())
- {
- cout<<vec[cur]->key<<" ";
- if(NULL != vec[cur]->left)
- {
- vec.push_back(vec[cur]->left);
- }
- if(NULL != vec[cur]->right)
- {
- vec.push_back(vec[cur]->right);
- }
- cur++;
- }
- }
- void AllOrderTraverse( AVLNode* root)
- {
- cout << "PreOrder: ";
- PreOrderTraverse(root);
- cout << endl;
- cout << "InOrder: ";
- InOrderTraverse(root);
- cout << endl;
- cout << "PostOrder: ";
- PostOrderTraverse(root);
- cout << endl;
- cout << "LevelOrder: ";
- LevelTraverse(root);
- cout << endl;
- }
- int main()
- {
- AVLTree* tree = CreateAVLTree();
- for(int i = 1; i <= 7; i++)
- {
- AVLInsert(tree->root, i);
- }
- for(int i = 16; i >= 10; i--)
- {
- AVLInsert(tree->root, i);
- }
- AVLInsert(tree->root, 8);
- AVLInsert(tree->root, 9);
- AllOrderTraverse(tree->root);
- cout<<endl;
- int total = TotalNodeNum(tree->root);
- int leaf = LeafNodeNum(tree->root);
- int node2 = leaf-1;//前提是leaf > 1
- int node1 = total - leaf - node2;
- return 0;
- }