AVL
AVL在计算机科学中最先发明的自平衡二叉树,得名于它的发明者G.M. Adelson-Velsky, E.M. Landis。
主要特点:AVL树种任何节点的两个子树的高度最大差别为1。
为了保持该特点,AVL可以在进行插入或删除时,采用四种方式进行旋转,分别是LL, LR, RR, RL。
说明
1.该代码没有采用模板的形式实现,采用的key为int类型。事实上,任何能够进行比较大小的类,在实现了比较函数之后,都可以应用到AVL中;
2.删除逻辑上有一点瑕疵,采用的是替换key的方式,不是替换node;
3.该代码没有经过大数据集的测试,欢迎读者测试指正;
4.删除逻辑有部分借鉴自该博客;
5.关于AVL的介绍网上有很多,这里不介绍了。
代码
//============================================================================
// Name : hello.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <cstring>
#ifndef NULL
#define NULL ((void *) 0)
#endif
using namespace std;
// AVL node
struct AVLNode{
AVLNode* left; // 左节点
AVLNode* right; // 右节点
int key; // 键值 整数
int height; // 高度
int symm; // 平衡
AVLNode(int key){
this->left = NULL;
this->right = NULL;
this->height = 0;
this->symm = 0;
this->key = key;
}
};
// AVL tree
// unique key tree
class AVLTree{
private:
AVLNode* root;
int insertIter(AVLNode* current, AVLNode* newNode);
void switchOp(AVLNode* current, int flag, int childDir);
void updateNode(AVLNode* node);
void findOperator(AVLNode**& dir, AVLNode* node, int flag);
void prePrint(AVLNode* node);
void inPrint(AVLNode* node);
void posPrint(AVLNode* node);
void LL(AVLNode* current, int flag);
void LR(AVLNode* current, int flag);
void RL(AVLNode* current, int flag);
void RR(AVLNode* current, int flag);
int remove(AVLNode* current, int key);
int findMax(AVLNode* node);
int findMin(AVLNode* node);
void freeNodes(AVLNode* node);
public:
AVLTree();
~AVLTree();
void insert(int key); // 插入
void prePrint(); // 前序遍历
void inPrint(); // 中序遍历
void posPrint(); // 后序遍历
void remove(int key); // 删除
};
/************************init and free**********************************/
AVLTree::AVLTree(){
this->root = NULL;
}
AVLTree::~AVLTree(){
freeNodes(root);
}
void AVLTree::freeNodes(AVLNode* node){
if(!node){
return;
}else{
freeNodes(node->left);
freeNodes(node->right);
delete node;
}
}
/***************************insert*************************************/
void AVLTree::insert(int key){
AVLNode* newNode = new AVLNode(key);
if(!root){
root = newNode;
}else{
int flag = insertIter(root, newNode);
switchOp(root, flag, 2);
}
}
int AVLTree::insertIter(AVLNode* current, AVLNode* newNode){
int returnValue; // 0 for left, 1 for right
int dir; // 0 for left, 1 for right, 2 for LL, 4 for LR, 6 for RR, 8 for RL
if(newNode->key < current->key){ // 分向左边
if(current->left){
dir = insertIter(current->left, newNode);
switchOp(current, dir, 0);
}else{
current->left = newNode;
}
returnValue = 0; // 告诉上级, 下级去哪了
}else{
if(current->right){
dir = insertIter(current->right, newNode);
switchOp(current, dir, 1);
}else{
current->right = newNode;
}
returnValue = 1;
}
// 更新 节点 信息
updateNode(current);
if(current->symm > 1){ // L
if(dir==0){
returnValue = 2; // LL
}else if(dir==1){
returnValue = 4; // LR
}
}else if(current->symm <-1){ // R
if(dir==0){
returnValue = 8; // RL
}else if(dir==1){
returnValue = 6; // RR
}
}
return returnValue;
}
/****************************remove*************************************/
void AVLTree::remove(int key){
if(!root){
return ;
}else{
int flag = remove(root, key);
switchOp(root, flag, 2);
}
}
int AVLTree::remove(AVLNode* current, int key){
if(!current){
return -2;
}else{
int dir; // -1 for 子节点被删, 0 for 左边较高 1 for 右边较高 , 2 for LL ........
if(current->key > key){ // 左子树
dir = remove(current->left, key);
if(dir == -1)
current->left = NULL;
else switchOp(current, dir, 0);
}else if(current->key < key){ // 右子树
dir = remove(current->right, key);
if(dir == -1)
current->right = NULL;
else switchOp(current, dir, 2);
}else{ // 该节点
if(!current->left && !current->right){ // 两个子树为空
delete current; // 删除
return -1;
}else{
if(current->symm > 0){ // 左子树较高
int leftMaxKey = findMax(current->left);
current->key = leftMaxKey;
dir = remove(current->left, leftMaxKey);
if(dir == -1)
current->left = NULL;
else switchOp(current, dir, 1);
}else{
int rightMinKey = findMin(current->right);
current->key = rightMinKey;
dir = remove(current->right, rightMinKey);
if(dir == -1)
current->right = NULL;
else switchOp(current, dir, 2);
}
}
}
// 更新节点 信息
updateNode(current);
int returnValue;
if(current->symm > 1){ // L
if(current->left->symm>0){
returnValue = 2; // LL
}else {
returnValue = 4; // LR
}
}else if(current->symm <-1){ // R
if(current->right->symm<0){
returnValue = 6; // RR
}else {
returnValue = 8; // RL
}
}
return returnValue;
}
}
/*****************************common*************************************/
int AVLTree::findMax(AVLNode* node){
AVLNode* tmp = node;
while(tmp->right){
tmp = tmp->right;
}
return tmp->key;
}
int AVLTree::findMin(AVLNode* node){
AVLNode* tmp = node;
while(tmp->left){
tmp = tmp->left;
}
return tmp->key;
}
void AVLTree::updateNode(AVLNode* node){
int leftHeight = node->left ? node->left->height+1:0;
int rightHeight = node->right ? node->right->height+1:0;
node->height = leftHeight > rightHeight ? leftHeight:rightHeight;
node->symm = leftHeight - rightHeight;
}
void AVLTree::switchOp(AVLNode* current, int flag, int childDir){
switch(flag){
case 2:
LL(current, childDir);
break;
case 4:
LR(current, childDir);
break;
case 6:
RR(current, childDir);
break;
case 8:
RL(current, childDir);
break;
default:
break;
}
}
void AVLTree::findOperator(AVLNode**& dir, AVLNode* node, int flag){
switch(flag){
case 0:
dir = &(node->left);
break;
case 1:
dir = &(node->right);
break;
case 2:
dir = &(root);
break;
default:
break;
}
}
/***********************operation**********************************/
//
// A
// / B
// B -----> / \
// / \ C A
// C D /
// D
//
void AVLTree::LL(AVLNode* current, int flag){
AVLNode* (*dir);
findOperator(dir, current, flag);
AVLNode* A = *dir;
AVLNode* B = A->left;
AVLNode* D = B->right;
*dir = B;
B->right = A;
A->left = D;
updateNode(A);
updateNode(B);
}
//
// A
// / C
// B ------> / \
// \ / \
// C B A
// / \ \ /
// D E D E
//
//
void AVLTree::LR(AVLNode* current, int flag){
AVLNode** dir;
findOperator(dir, current, flag);
AVLNode* A = *dir;
AVLNode* B = A->left;
AVLNode* C = B->right;
AVLNode* D = C->left;
AVLNode* E = C->right;
*dir = C;
C->left = B;
C->right = A;
B->right = D;
A->left = E;
updateNode(B);
updateNode(A);
updateNode(C);
}
//
// A
// \ C
// B --------> / \
// / / \
// C A B
// / \ \ /
// D E D E
//
void AVLTree::RL(AVLNode* current, int flag){
AVLNode** dir;
findOperator(dir, current, flag);
AVLNode* A = *dir;
AVLNode* B = A->right;
AVLNode* C = B->left;
AVLNode* D = C->left;
AVLNode* E = C->right;
*dir = C;
C->left = A;
C->right = B;
B->left = E;
A->right = D;
updateNode(B);
updateNode(A);
updateNode(C);
}
//
// A
// \ B
// B -----> / \
// / \ A C
// D C \
// D
//
void AVLTree::RR(AVLNode* current, int flag){
AVLNode** dir;
findOperator(dir, current, flag);
AVLNode* A = *dir;
AVLNode* B = A->right;
AVLNode* D = B->left;
*dir = B;
B->left = A;
A->right = D;
updateNode(A);
updateNode(B);
}
/***************************printer***********************************/
void AVLTree::prePrint(){
prePrint(root);
cout << endl;
}
void AVLTree::prePrint(AVLNode* node){
if(!node){
return;
}else{
cout << node->key <<" ";
prePrint(node->left);
prePrint(node->right);
}
}
void AVLTree::inPrint(){
inPrint(root);
cout << endl;
}
void AVLTree::inPrint(AVLNode* node){
if(!node){
return;
}else{
inPrint(node->left);
cout << node->key <<" ";
inPrint(node->right);
}
}
void AVLTree::posPrint(){
posPrint(root);
cout << endl;
}
void AVLTree::posPrint(AVLNode* node){
if(!node){
return;
}else{
posPrint(node->left);
posPrint(node->right);
cout << node->key <<" ";
}
}
/***************************main**********************************/
int main() {
int num;
cin >> num ;
AVLTree tree ;
int value;
for(int i = 0; i < num; i++){
cin >> value;
tree.insert(value);
}
// remove operation
cin >> num;
for(int i = 0; i < num; i++){
cin >> value;
tree.remove(value);
}
tree.prePrint();
tree.inPrint();
tree.posPrint();
return 0;
}
运行
节点数目:16
节点顺序:3 2 1 4 5 6 7 16 15 14 13 12 11 10 8 9
删除数目:3
删除顺序:6 5 1
前序遍历:11 7 3 4 9 8 10 13 12 15 14 16
中序遍历:3 4 7 8 9 10 11 12 13 14 15 16
后序遍历:4 3 8 10 9 7 12 14 16 15 13 11