- AVL树
- AVL树节点定义
- 平衡方式
- LL形
- LR形
- RR形
- RL形
- 完整插入代码
AVL 树是一种平衡二叉树,得名于其发明者的名字( Adelson-Velskii 以及 Landis)。
平衡二叉树递归定义如下:
-
什么是二叉搜索树
任一结点 小于 其左子树的所有结点小于 其右子树的所有结点;
结点的左右子树,也是二叉排序树;
-
什么是AVL树
搜索二叉树的每个结点的左、右子树高度之差的绝对值不超过1.
同时引入平衡因子的概念,即:结点的平衡因子= 右子树高度 – 左子树高度
节点包括:
| AVLTreeNode | Type |
|---|---|
| val(节点值) | int |
| bf(平衡因子) | int |
| leftTree(左子树) | AVLTreeNode* |
| leftTree(右子树) | AVLTreeNode* |
定义如下:
struct AVLTreeNode
{
int val; // 节点值
int bf; // 平衡因子
AVLTreeNode* leftTree; // 左子树
AVLTreeNode* rightTree; // 右子树
AVLTreeNode() :val(0), bf(0), leftTree(NULL), rightTree(NULL) {}
AVLTreeNode(int valable) :val(valable), bf(0), leftTree(NULL), rightTree(NULL) {}
AVLTreeNode(int valable, int be, AVLTreeNode* lf, AVLTreeNode* rf) :val(valable), bf(be), leftTree(lf), rightTree(rf) {}
AVLTreeNode* setAVLTree(vector nums); // 插入平衡算法
};
平衡方式
LL形
- 不平衡原因:新结点插入到A的左子女的左子树中导致不平衡
算法:
void rotateLL(AVLTreeNode*& root) {
AVLTreeNode* currL = root;
root = currL->rightTree;
currL->rightTree = root->leftTree;
root->leftTree = currL;
root->bf = currL->bf = 0;
}
图示:
- 不平衡原因:新结点插入到A的右子女的右子树中导致不平衡
算法示例:
void rotateRR(AVLTreeNode*& root) {
AVLTreeNode* curr = root;
root = curr->leftTree;
curr->leftTree = root->rightTree;
root->rightTree = curr;
root->bf = curr->bf = 0;
}
图示过程:
- 不平衡原因:新结点插入到A的左子女的右子树中导致不平衡
算法示例:
void rotateLR(AVLTreeNode*& root) {
AVLTreeNode* currL = root->leftTree;
AVLTreeNode* currR = root;
root = currL->rightTree;
currL->rightTree = root->leftTree;
root->leftTree = currL;
if (root->bf <= 0)currL->bf = 0;
else
currL->bf = -1;
currR->leftTree = root->rightTree;
root->rightTree = currR;
if (root->bf == -1)
currR->bf = 1;
else
currR->bf = 0;
root->bf = 0;
}
图示过程:
- 不平衡原因:新结点插入到A的右子女的左子树中导致不平衡
算法示例:
void rotateRL(AVLTreeNode*& root) {
AVLTreeNode* currL = root;
AVLTreeNode* currR = currL->rightTree;
root = currR->leftTree;
currL->rightTree = root->leftTree;
root->leftTree = currL;
if (root->bf == 1)
currL->bf = -1;
else
currL->bf = 0;
currR->leftTree = root->rightTree;
root->rightTree = currR;
if (root->bf >= 0)
currR->bf = 0; else
currR->bf = 1;
root->bf = 0;
}
图示过程:
AVLTreeNode.h
#pragma once #ifndef AVLTREENODE_H #define AVLTREENODE_H #include#include using namespace std; class AVLTreeNode { public: int val; int bf; // 平衡因子 AVLTreeNode* leftTree; AVLTreeNode* rightTree; AVLTreeNode() :val(0), bf(0), leftTree(NULL), rightTree(NULL) {} AVLTreeNode(int valable) :val(valable), bf(0), leftTree(NULL), rightTree(NULL) {} AVLTreeNode(int valable, int be, AVLTreeNode* lf, AVLTreeNode* rf) :val(valable), bf(be), leftTree(lf), rightTree(rf) {} AVLTreeNode* setAVLTree(vector nums); }; #endif // !AVLTREENODE_H
AVLTreeNode.cpp
#include "AVLTreeNode.h" #include#include #include AVLTreeNode* AVLTreeNode::setAVLTree(vector nums) { AVLTreeNode* curr_fa = NULL, *root, *curr_ch; if (nums.empty())return NULL; root = new AVLTreeNode(nums[0]); curr_ch = root; stack set_way_save; for (int i = 1; i < nums.size(); i++) { while (curr_ch) // 查找应该插入的位置 { if (nums[i] == curr_ch->val) { break; continue; } set_way_save.push(curr_ch); if (nums[i] < curr_ch->val)curr_ch = curr_ch->leftTree; else curr_ch = curr_ch->rightTree; } AVLTreeNode* node = new AVLTreeNode(nums[i]); curr_ch = set_way_save.top(); if (node->val < curr_ch->val) curr_ch->leftTree = node; else curr_ch->rightTree = node; while (!set_way_save.empty()) { curr_ch = set_way_save.top(); set_way_save.pop(); if (curr_ch->leftTree == node) curr_ch->bf--; else curr_ch->bf++; if (curr_ch->bf == 0)break; else if (curr_ch->bf == 1 || curr_ch->bf == -1) { node = curr_ch; } else { if (curr_ch->bf < 0) { if (node->bf < 0) rotateRR(curr_ch); else rotateLR(curr_ch); } else { if (node->bf < 0) rotateRL(curr_ch); else rotateLL(curr_ch); } break; } } } return root; } void rotateLL(AVLTreeNode*& root) { AVLTreeNode* currL = root; root = currL->rightTree; currL->rightTree = root->leftTree; root->leftTree = currL; root->bf = currL->bf = 0; } void rotateRR(AVLTreeNode*& root) { AVLTreeNode* curr = root; root = curr->leftTree; curr->leftTree = root->rightTree; root->rightTree = curr; root->bf = curr->bf = 0; } void rotateLR(AVLTreeNode*& root) { AVLTreeNode* currL = root->leftTree; AVLTreeNode* currR = root; root = currL->rightTree; currL->rightTree = root->leftTree; root->leftTree = currL; if (root->bf <= 0)currL->bf = 0; else currL->bf = -1; currR->leftTree = root->rightTree; root->rightTree = currR; if (root->bf == -1) currR->bf = 1; else currR->bf = 0; root->bf = 0; } void rotateRL(AVLTreeNode*& root) { AVLTreeNode* currL = root; AVLTreeNode* currR = currL->rightTree; root = currR->leftTree; currL->rightTree = root->leftTree; root->leftTree = currL; if (root->bf == 1) currL->bf = -1; else currL->bf = 0; currR->leftTree = root->rightTree; root->rightTree = currR; if (root->bf >= 0) currR->bf = 0; else currR->bf = 1; root->bf = 0; }



