数据结构(十)二叉平衡树
二叉平衡树–c++实现
AVL树
定义:一颗空的二叉树是AVL树;如果T是一颗非空的二叉树, T L 和 T R T_L和T_R TL和TRf分别是其左子树和右子树,那么当T满足以下条件时,T是一颗AVL树:
-
T L 和 T R T_L和T_R TL和TR是AVL树
-
∣ h L − h R ∣ ≤ 1 |h_L - h_R| \le 1 ∣hL−hR∣≤1,其中 h L 和 h R 分别是 T L 和 T R h_L和h_R分别是T_L和T_R hL和hR分别是TL和TR的高.
一颗AVL搜索树既是二叉搜索树,也是AVL树。
AVL树的描述
template<class K,class E> struct AVLNode{
K key;
E value;
AVLNode<K,E> *leftChild,*rightChild;
int height;
AVLNode(){
leftChild = rightChild = nullptr;
height = 0;
}
AVLNode(K theKey,E theValue){
key = theKey;
value = theValue;
leftChild = rightChild = nullptr;
height = 1;
}
};
template<class K, class E>
class AVLTree {
private:
AVLNode<K,E> *root;
AVLNode<K,E>* leftRotation(AVLNode<K,E>* proot); // 单左旋
AVLNode<K,E>* rightRotation(AVLNode<K,E>* proot);// 右单旋
AVLNode<K,E>* rightLeftRotation(AVLNode<K,E>* proot);//先右旋再左旋
AVLNode<K,E>* leftRightRotation(AVLNode<K,E>* proot);//先左旋再右旋
int height(AVLNode<K,E>* proot);
public:
AVLTree();
~AVLTree();
int getSize() const;
AVLNode<K,E>* find(K theKey) const;
void insert(K theKey, E theValue);
void del(K theKey);
};
AVL树的实现
#include "AVLTree.h"
#include <algorithm>
using namespace std;
template<class K, class E>
AVLNode<K, E> *AVLTree<K, E>::leftRotation(AVLNode<K, E> *proot) {
AVLNode<K, E> *prchild = proot->rightChild;
proot->rightChild = prchild->leftChild;
prchild->leftChild = proot;
proot->height = max(proot->leftChild->height, proot->rightChild->height) + 1; //更新节点的高度值
prchild->height = max(prchild->leftChild->height, prchild->rightChild->height) + 1; //更新节点的高度值
return prchild;
}
template<class K, class E>
AVLNode<K, E> *AVLTree<K, E>::rightRotation(AVLNode<K, E> *proot) {
AVLNode<K, E> *plchild = proot->leftChild;
proot->leftChild = plchild->rightChild;
plchild->rightChild = proot;
proot->height = max(proot->leftChild->height, proot->rightChild->height) + 1;
plchild->height = max(plchild->leftChild->height, plchild->rightChild->height) + 1;
return plchild;
}
template<class K, class E>
AVLNode<K, E> *AVLTree<K, E>::rightLeftRotation(AVLNode<K, E> *proot) {
proot->rightChild = rightRotation(proot->rightChild);
return leftRotation(proot);
}
template<class K, class E>
AVLNode<K, E> *AVLTree<K, E>::leftRightRotation(AVLNode<K, E> *proot) {
proot->leftChild = leftRotation(proot->leftChild);
return rightRotation(proot);
}
template<class K, class E>
int AVLTree<K, E>::height(AVLNode<K, E> *proot) {
if (proot == nullptr) return 0;
else {
int lefth = height(proot->leftChild);
int righth = height(proot->rightChild);
return max(lefth, righth) + 1;
}
}
template<class K, class E>
AVLTree<K, E>::AVLTree() {
root = nullptr;
}
template<class K, class E>
AVLTree<K, E>::~AVLTree() {
}
template<class K, class E>
int AVLTree<K, E>::getSize() const {
return 1;
}
template<class K, class E>
AVLNode<K, E> *AVLTree<K, E>::find(K theKey) const {
AVLNode<K, E> *p = root;
while (p->key != theKey) {
if (p->key > theKey) p = p->leftChild;
else p = p->rightChild;
}
return p;
}
template<class K, class E>
void AVLTree<K, E>::insert(K theKey, E theValue) {
if (root == nullptr) {
root = new AVLNode<K, E>(theKey, theValue);
root->height = 1;
return;
}
AVLNode<K, E> *p = root;
AVLNode<K, E> *pr = nullptr; //p的双亲
AVLNode<K, E> *prp = nullptr;//prp的双亲
while (p != nullptr) {
prp = pr;
pr = p;
if (theKey > p->key) {
p = p->rightChild;
} else {
p = p->leftChild;
}
}
if (pr->key > theKey) pr->leftChild = new AVLNode<K, E>(theKey, theValue);
else pr->rightChild = new AVLNode<K, E>(theKey, theValue);
if (prp == nullptr) return;
if (height(prp->rightChild) - height(prp->leftChild) == 2) {
if (theKey > pr->key) prp = leftRotation(prp);
else if (theKey < pr->key) prp = rightLeftRotation(prp);
return;
} else if (height(prp->leftChild) - height(prp->rightChild) == 2) {
if (theKey > pr->key) prp = rightRotation(prp);
else if (theKey < pr->key) prp = leftRightRotation(prp);
return;
}
}
template<class K, class E>
void AVLTree<K, E>::del(K theKey) { //删除节点时,如果节点同时拥有左子树和右子树,
// 则在高度高的子树上选择最大(或最小)元素进行替换,这样能保证替换后不会再出现失衡的现
AVLNode<K, E> *p = root,
*pp = nullptr,
*ppp = nullptr;
while (p->key != theKey) {
ppp = pp;
pp = p;
if (theKey > p->key) p = p->rightChild;
else p = p->leftChild;
}
if (p->leftChild != nullptr && p->rightChild != nullptr) {
if (height(p->leftChild) > height(p->rightChild)) {
AVLNode<K, E> *pl = p->leftChild, *plp = p;
while (pl->rightChild != nullptr) {
plp = pl;
pl = pl->rightChild;
}
K k = pl->key;
E v = pl->value;
del(k);
p->key = k;
p->value = v;
plp->rightChild = nullptr;
} else {
AVLNode<K, E> *pl = p->rightChild, *plp = p;
while (pl->leftChild != nullptr) {
p = pl;
pl = pl->leftChild;
}
K k = pl->key;
E v = pl->value;
del(k);
p->key = k;
p->value = v;
plp->leftChild = nullptr;
}
} else if (p->leftChild == nullptr && p->rightChild == nullptr) {
if (theKey > pp->key) {
delete p;
pp->rightChild = nullptr;
if (height(pp->leftChild) - height(pp->rightChild) == 2) {
if (pp->leftChild->leftChild != nullptr) {
ppp = rightRotation(ppp);
return;
} else {
ppp = leftRightRotation(ppp);
return;
}
}
}
else if (theKey < pp->key)
delete p;
pp->leftChild = nullptr;
if (height(pp->rightChild) - height(pp->leftChild) == 2){
if (pp->rightChild->rightChild != nullptr){
ppp = leftRotation(ppp);
return;
} else{
ppp = rightLeftRotation(ppp);
return;
}
}
}else{
if (theKey > pp->key) {
pp->rightChild = p->leftChild != nullptr ? p->leftChild:p->rightChild;
delete p;
} else{
pp->leftChild = p->leftChild != nullptr ? p->leftChild:p->rightChild;
delete p;
}
}
}