AVL树根据平衡特性和二叉搜索树的特性递归实现插入、删除。
//
// Created by hpf on 18-6-21.
//
#ifndef AVLTREE_AVLTREE_H
#define AVLTREE_AVLTREE_H
#include <algorithm>
#include <iostream>
#include <vector>
template<typename Key, typename Value>
class AVLTree {
private:
struct Node {
Key key;
Value value;
Node *left;
Node *right;
int height;
Node(Key key, Value value) {
this->key = key;
this->value = value;
this->left = this->right = nullptr;
height = 1;
}
Node(Node *node) {
this->key = node->key;
this->value = node->value;
this->left = node->left;
this->right = node->right;
this->height = node->height;
}
};
Node *root;
int size;
public:
AVLTree() {
root = nullptr;
size = 0;
}
~AVLTree() {
destroy(root);
}
int getSize() {
return size;
}
int isEmpty() {
return size == 0;
}
int getHeight(Node *node) {
if (node == nullptr) {
return 0;
}
return node->height;
}
int getBalanceFactor(Node *node) {
if (node == nullptr) {
return 0;
}
return getHeight(node->left) - getHeight(node->right);
}
bool isBST() {
std::vector<Key> keys;
inOrder(root, keys);
for (int i = 1; i < keys.size(); ++i) {
if (keys.at(i - 1) < keys.at(i)) {
return false;
}
}
return true;
}
bool isBalanced() {
return isBalanced(root);
}
void add(Key key, Value value) {
root = add(root, key, value);
}
bool contains(Key key) {
return getNode(root, key) != nullptr;
}
Value *get(Key key) {
Node *node = getNode(root, key);
return node == nullptr ? nullptr : &(node->value);
}
void set(Key key, Value newValue) {
Node *node = getNode(root, key);
if (node != nullptr) {
node->value = newValue;
}
}
// 从二叉树中删除键值为key的节点
Value *remove(Key key) {
Node *node = getNode(root, key);
if (node != nullptr) {
root = remove(root, key);
return &(node->value);
}
return nullptr;
}
private:
// 向以node为根的二叉搜索树中,插入节点(key, value)
// 返回插入新节点后的二叉搜索树的根
Node *add(Node *node, Key key, Value value) {
if (node == nullptr) {
size++;
return new Node(key, value);
}
if (key == node->key) {
node->value = value;
} else if (key < node->key) {
node->left = add(node->left, key, value);
} else {
node->right = add(node->right, key, value);
}
node->height = 1 + std::max(getHeight(node->left), getHeight(node->right));
int balanceFactor = getBalanceFactor(node);
if (balanceFactor > 1 && getBalanceFactor(node->left) >= 0) {
return rightRotate(node);
}
if (balanceFactor < -1 && getBalanceFactor(node->right) <= 0) {
return leftRotate(node);
}
if (balanceFactor > 1 && getBalanceFactor(node->left) < 0) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
if (balanceFactor < -1 && getBalanceFactor(node->right) > 0) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
return node;
}
// 在以node为根的二叉搜索树中查找key所对应的Node
Node *getNode(Node *node, Key key) {
if (node == nullptr) {
return nullptr;
}
if (key == node->key) {
return node;
} else if (key < node->key) {
return getNode(node->left, key);
} else {
return getNode(node->right, key);
}
}
void destroy(Node *node) {
if (node != nullptr) {
destroy(node->left);
destroy(node->right);
delete node;
size--;
}
}
// 在以node为根的二叉搜索树中,返回最小键值的节点
Node *minimum(Node *node) {
if (node->left == nullptr)
return node;
return minimum(node->left);
}
// 在以node为根的二叉搜索树中,返回最大键值的节点
Node *maximum(Node *node) {
if (node->right == nullptr)
return node;
return maximum(node->right);
}
// 删除掉以node为根的二分搜索树中的最小节点
// 返回删除节点后新的二分搜索树的根
Node *removeMin(Node *node) {
if (node->left == nullptr) {
Node *rightNode = node->right;
delete node;
size--;
return rightNode;
}
node->left = removeMin(node->left);
return node;
}
// 删除掉以node为根的二分搜索树中的最大节点
// 返回删除节点后新的二分搜索树的根
Node *removeMax(Node *node) {
if (node->right == nullptr) {
Node *leftNode = node->left;
delete node;
size--;
return leftNode;
}
node->right = removeMax(node->right);
return node;
}
// 删除掉以node为根的二分搜索树中键值为key的节点
// 返回删除节点后新的二分搜索树的根
Node *remove(Node *node, Key key) {
if (node == nullptr) {
return nullptr;
}
Node *retNode;
if (key < node->key) {
node->left = remove(node->left, key);
retNode = node;
} else if (key > node->key) {
node->right = remove(node->right, key);
retNode = node;
} else {
if (node->left == nullptr) {
Node *rightNode = node->right;
delete node;
size--;
retNode = rightNode;
} else if (node->right == nullptr) {
Node *leftNode = node->left;
delete node;
size--;
retNode = leftNode;
} else {
Node *successor = new Node(minimum(node->right));
size++;
successor->right = remove(node->right, successor->key);
successor->left = node->left;
delete node;
size--;
retNode = successor;
}
}
if (retNode == nullptr) {
return nullptr;
}
retNode->height = 1 + std::max(getHeight(retNode->left), getHeight(retNode->right));
int balanceFactor = getBalanceFactor(retNode);
if (balanceFactor > 1 && getBalanceFactor(retNode->left) >= 0) {
return rightRotate(retNode);
}
if (balanceFactor < -1 && getBalanceFactor(retNode->right) <= 0) {
return leftRotate(retNode);
}
if (balanceFactor > 1 && getBalanceFactor(retNode->left) < 0) {
retNode->left = leftRotate(retNode->left);
return rightRotate(retNode);
}
if (balanceFactor < -1 && getBalanceFactor(retNode->right) > 0) {
retNode->right = rightRotate(retNode->right);
return leftRotate(retNode);
}
return retNode;
}
void inOrder(Node *node, std::vector<Key> keys) {
if (node == nullptr) {
return;
}
inOrder(node->left, keys);
keys.push_back(node->key);
inOrder(node->right, keys);
}
bool isBalanced(Node *node) {
if (node == nullptr) {
return true;
}
int balanceFactor = getBalanceFactor(node);
if (std::abs(balanceFactor) > 1) {
return false;
}
return isBalanced(node->left) && isBalanced(node->right);
}
Node *leftRotate(Node *y) {
Node *x = y->right;
Node *tmp = x->left;
x->left = y;
y->right = tmp;
y->height = std::max(getHeight(y->left), getHeight(y->right)) + 1;
x->height = std::max(getHeight(x->left), getHeight(x->right)) + 1;
return x;
}
Node *rightRotate(Node *y) {
Node *x = y->left;
Node *tmp = x->right;
x->right = y;
y->left = tmp;
y->height = std::max(getHeight(y->left), getHeight(y->right)) + 1;
x->height = std::max(getHeight(x->left), getHeight(x->right)) + 1;
return x;
}
};
#endif //AVLTREE_AVLTREE_H
AVL树的非递归实现插入和查找(根据平衡因子的判断)
四种旋转原则:
1、保持搜索树特性
2、左右相对平衡
#pragma once
#include<iostream>
#include<cassert>
#include<vector>
using namespace std;
template<class K,class V>
struct AVLTreeNode {
pair<K, V>kv;
AVLTreeNode<K, V>* left;
AVLTreeNode<K, V>* right;
AVLTreeNode<K, V>* parent;
//右子树-左子树(高度差)
int bf = 0;
AVLTreeNode(const pair<K, V>& kv) :
kv(kv), left(nullptr), right(nullptr), parent(nullptr),bf(0)
{}
};
template<class K,class V>
class AVLTress {
typedef AVLTreeNode<K, V> Node;
private:
Node* root = nullptr;
void RotateL(Node* parent) {
Node* subR = parent->right;
Node* subRL = subR->left;
parent->right = subRL;
if (subRL)
{
subRL->parent = parent;
}
subR->left = parent;
Node* pparent = parent->parent;
parent->parent = subR;
if (parent == root)
{
root = subR;
root->parent = nullptr;
}
else
{
if (parent == pparent->left)
{
pparent->left = subR;
}
else{
pparent->right = subR;
}
subR->parent = pparent;
}
subR->bf = parent->bf = 0;
}
void RotateR(Node* parent) {
Node* subL = parent->left;
Node* subLR = subL->right;
parent->left = subLR;
if (subLR)
{
subLR->parent = parent;
}
Node* pparent = parent->parent;
subL->right = parent;
parent->parent = subL;
if (parent == root)
{
root = subL;
root->parent = nullptr;
}
else
{
if (parent == pparent->left)
{
pparent->left = subL;
}
else {
pparent->right = subL;
}
subL->parent = pparent;
}
subL->bf = parent->bf = 0;
}
void RotateLR(Node* parent) {
Node* subL = parent->left;
Node* subLR = subL->right;
int bf = subLR->bf;
RotateL(parent->left);
RotateR(parent);
if (bf == 0)
{
subL->bf = 0;
subLR->bf = 0;
parent->bf = 0;
}
else if (bf == -1)
{
subL->bf = 0;
subLR->bf = 0;
parent->bf = 1;
}
else if (bf == 1)
{
subL->bf = -1;
subLR->bf = 0;
parent->bf = 0;
}
else
{
assert(false);
}
}
void RotateRL(Node* parent) {
Node* subR = parent->right;
Node* subRL = subR->left;
int bf = subRL->bf;
RotateR(parent->right);
RotateL(parent);
if (bf == 0)
{
subR->bf = 0;
subRL->bf = 0;
parent->bf = 0;
}
else if (bf == -1)
{
subR->bf = 1;
subRL->bf = 0;
parent->bf = 0;
}
else if (bf == 1)
{
subR->bf = 0;
subRL->bf = 0;
parent->bf = -1;
}
else
{
assert(false);
}
}
int _Height(Node* node) {
if (node == nullptr)
{
return 0;
}
int LH = _Height(node->left);
int RH = _Height(node->right);
return (LH < RH) ? RH + 1 : LH + 1;
}
bool _IsBalanceTree(Node* node) {
if (node == nullptr)
{
return true;
}
int RTH = _Height(node->right);
int LTH = _Height(node->left);
int diff = RTH - LTH;
if (abs(diff) >= 2)
{
cout << node->kv.first << "节点平衡因子异常" << endl;
return false;
}
else if (diff != node->bf) {
cout << node->kv.first << "节点平衡因子有误" << endl;
}
return _IsBalanceTree(node->left) && _IsBalanceTree(node->right);
}
void _InOrder(Node* node) {
if (node == nullptr)
{
return;
}
_InOrder(node->left);
cout << node->kv.first << " ";
_InOrder(node->right);
}
public:
int Height() {
return _Height(root);
}
bool IsBalanceTree() {
return _IsBalanceTree(root);
}
void InOrder() {
_InOrder(root);
cout << endl;
}
bool Insert(const pair<K, V>& kv) {
if (root == nullptr)
{
root = new Node(kv);
return true;
}
Node* cur = root;
Node* parent = nullptr;
while (cur)
{
if (cur->kv.first < kv.first) {
parent = cur;
cur = cur->right;
}
else if (cur->kv.first > kv.first)
{
parent = cur;
cur = cur->left;
}
else
{
return false;
}
}
cur = new Node(kv);
if (parent->kv.first < cur->kv.first)
{
parent->right = cur;
}
else if (parent->kv.first > cur->kv.first) {
parent->left = cur;
}
cur->parent = parent;
while (parent)
{
if (cur == parent->left)
{
--parent->bf;
}
else if (cur == parent->right) {
++parent->bf;
}
if (parent->bf == 0)
{
break;
}
else if (parent->bf == 1 || parent->bf == -1)
{
cur = cur->parent;
parent = parent->parent;
}
else if (parent->bf == 2 || parent->bf == -2) {
if (parent->bf == 2 && parent->right->bf == 1)
{
RotateL(parent);
}
else if (parent->bf == -2 && parent->left->bf == -1) {
RotateR(parent);
}
else if (parent->bf == -2 && parent->left->bf == 1)
{
RotateLR(parent);
}
else if (parent->bf == 2 && parent->right->bf == -1)
{
RotateRL(parent);
}
break;
}
else
{
assert(false);
}
}
}
};
void testAVLTree() {
const int N = 1000;
vector<int>v;
srand(time(0));
for (size_t i = 0; i < N; i++)
{
//v.push_back(i);
v.push_back(rand());
}
AVLTress<int, int>avlTree;
for (auto e : v) {
avlTree.Insert(make_pair(e, e));
}
cout << "是否平衡?" << avlTree.IsBalanceTree() << endl;
cout << "高度 = " << avlTree.Height() << endl;
avlTree.InOrder();
}