平衡二叉树:在AVL树中,任何节点的两个子树的高度最大差别为 1
,所以它也被称为平衡二叉树 。
平衡因子:结点的平衡因子 = 左子树的高度 - 右子树的高度 。AVL树中所有结点平衡因子只能为-1,1或0。
#include<iostream>
#include<assert.h>
using namespace std;
typedef int KeyType;
typedef struct AVLNode
{
AVLNode* leftchild;
AVLNode* rightchild;
AVLNode* parent;
int balance;
KeyType key;
}AVLNode;
typedef struct
{
AVLNode* root;
int cursize;
}AVLTree;
AVLNode* BuyNode()
{
AVLNode* ptr = (AVLNode*)calloc(1, sizeof(AVLNode));
if (ptr == nullptr) exit(EXIT_FAILURE);
return ptr;
}
void FreeNode(AVLNode* ptr)
{
free(ptr);
}
void InitTree(AVLTree* ptree)
{
assert(ptree != nullptr);
ptree->root = nullptr;
ptree->cursize = 0;
}
AVLNode* FindValue(AVLTree* ptree, KeyType kx)
{
assert(ptree != nullptr);
AVLNode* ptr = ptree->root;
while (ptr != nullptr && ptr->key != kx)
{
ptr = ptr->key > kx ? ptr->leftchild : ptr->rightchild;
}
return ptr;
}
//返回中序遍历第一个结点
AVLNode* First(AVLNode* ptr)
{
while (ptr != nullptr && ptr->leftchild != nullptr)
{
ptr = ptr->leftchild;
}
return ptr;
}
//返回中序遍历结点的下一个结点
AVLNode* Next(AVLNode* ptr)
{
if (ptr == nullptr) return nullptr;
if (ptr->rightchild != nullptr)
{
return First(ptr->rightchild);
}
else
{
AVLNode* pa = ptr->parent;
while (pa != nullptr && pa->leftchild != ptr)
{
ptr = pa;
pa = ptr->parent;
}
return pa;
}
}
//非递归中序遍历
void NiceInOrder(AVLTree* ptree)
{
assert(ptree != nullptr);
for (AVLNode* ptr = First(ptree->root); ptr != nullptr; ptr = Next(ptr))
{
printf("balance:%3d Key:%3d\n", ptr->balance, ptr->key);
}
printf("\n");
}
//返回中序遍历最后一个结点
AVLNode* Last(AVLNode* ptr)
{
if (ptr == nullptr) return nullptr;
if (ptr->rightchild == nullptr) return ptr;
else return Last(ptr->rightchild);
}
//返回中序遍历结点的上一个结点
AVLNode* Prev(AVLNode* ptr)
{
if (ptr == nullptr) return nullptr;
if (ptr->leftchild != nullptr)
{
return Last(ptr->leftchild);
}
else
{
AVLNode* pa = ptr->parent;
while (pa != nullptr && pa->rightchild != ptr)
{
ptr = pa;
pa = ptr->parent;
}
return pa;
}
}
//非递归反向中序遍历
void ResNiceInOrder(AVLTree* ptree)
{
assert(ptree != nullptr);
for (AVLNode* ptr = Last(ptree->root); ptr != nullptr; ptr = Prev(ptr))
{
printf("%3d", ptr->key);
}
printf("\n");
}
AVLNode* RotateLeft(AVLTree* ptree, AVLNode* ptr)
{
assert(ptree != nullptr && ptr != nullptr);
AVLNode* newroot = ptr->rightchild;//1
newroot->parent = ptr->parent;
ptr->rightchild = newroot->leftchild;//2
if(newroot->leftchild!=nullptr)//无左孩子
{
newroot->leftchild->parent = ptr;
}
newroot->leftchild = ptr;//3
AVLNode* pa = ptr->parent;
if (pa == nullptr)//ptr是否为根
{
ptree->root = newroot;
}
else
{
if (pa->leftchild == ptr)
{
pa->leftchild = newroot;
}
else
{
pa->rightchild = newroot;
}
}
ptr->parent = newroot;
return newroot;
}
AVLNode* RotateRight(AVLTree* ptree, AVLNode* ptr)
{
assert(ptree != nullptr && ptr != nullptr);
AVLNode* newroot = ptr->leftchild;//1
newroot->parent = ptr->parent;
ptr->leftchild = newroot->rightchild;//2
if (newroot->rightchild != nullptr)//无右孩子
{
newroot->rightchild->parent = ptr;
}
newroot->rightchild = ptr;//3
AVLNode* pa = ptr->parent;
if (pa == nullptr)//ptr是否为根
{
ptree->root = newroot;
}
else
{
if (pa->leftchild == ptr)
{
pa->leftchild = newroot;
}
else
{
pa->rightchild = newroot;
}
}
ptr->parent = newroot;
return newroot;
}
AVLNode* LeftBalance(AVLTree* ptree, AVLNode* ptr)
{
assert(ptree != nullptr);
AVLNode* leftsub = ptr->leftchild, * rightsub = nullptr;
AVLNode* newroot = nullptr;
switch (leftsub->balance)
{
case 0:break;
case -1:
ptr->balance = 0;
leftsub->balance = 0;
newroot = RotateRight(ptree, ptr);
break;
case 1:
rightsub = leftsub->rightchild;
switch (rightsub->balance)
{
case 0:
ptr->balance = 0;
leftsub->balance = 0;
break;
case 1:
ptr->balance = 0;
leftsub->balance = -1;
break;
case -1:
ptr->balance = 1;
leftsub->balance = 0;
break;
}
rightsub->balance = 0;
RotateLeft(ptree, leftsub);
newroot = RotateRight(ptree, ptr);
break;
}
return newroot;
}
AVLNode* RightBalance(AVLTree* ptree, AVLNode* ptr)
{
assert(ptree != nullptr);
AVLNode* rightsub = ptr->rightchild, * leftsub = nullptr;
AVLNode* newroot = nullptr;
switch (rightsub->balance)
{
case 0:break;
case 1:
ptr->balance = 0;
rightsub->balance = 0;
newroot = RotateLeft(ptree, ptr);
break;
case -1:
leftsub = rightsub->leftchild;
switch (leftsub->balance)
{
case 0:
ptr->balance = 0;
rightsub->balance = 0;
break;
case 1:
ptr->balance = -1;
rightsub->balance = 0;
break;
case -1:
ptr->balance = 0;
rightsub->balance = 1;
break;
}
rightsub->balance = 0;
RotateRight(ptree, rightsub);
newroot = RotateLeft(ptree, ptr);
break;
}
return newroot;
}
void Adiust_Insert_Item(AVLTree* ptree, AVLNode* ptr)
{
assert(ptree != nullptr);
bool taller = true;
AVLNode* pa = ptr->parent;
while (pa != nullptr && taller)
{
if (pa->leftchild == ptr)
{
switch (pa->balance)
{
case 0:
pa->balance = -1;
break;
case 1:
pa->balance = 0;
break;
case -1:
LeftBalance(ptree, pa);
taller = false;
break;
}
}
else
{
switch (pa->balance)
{
case 0:
pa->balance =1;
break;
case -1:
pa->balance = 0;
break;
case 1:
RightBalance(ptree, pa);
taller = false;
break;
}
}
ptr = pa;
pa = ptr->parent;
}
}
bool Insert_Item(AVLTree* ptree, const KeyType kx)
{
assert(ptree != nullptr);
if (ptree->root == nullptr)
{
ptree->root = BuyNode();
ptree->root->key = kx;
ptree->cursize = 1;
return true;
}
AVLNode* ptr = ptree->root, * pa = nullptr;
while (ptr != nullptr && ptr->key != kx)
{
pa = ptr;
ptr = kx < ptr->key ? ptr->leftchild : ptr->rightchild;
}
if (ptr != nullptr && ptr->key == kx) return false;
ptr = BuyNode();
ptr->key = kx;
ptr->parent = pa;
if (kx < pa->key)
{
pa->leftchild = ptr;
}
else
{
pa->rightchild = ptr;
}
ptree->cursize += 1;
Adiust_Insert_Item(ptree, ptr);
return true;
}
bool Del_LeftBalance(AVLTree* ptree, AVLNode* &pa)
{
assert(ptree != nullptr && pa != nullptr);
AVLNode* leftsub = pa->leftchild, * rightsub = nullptr;
bool ret = false;
switch (leftsub->balance)
{
case 0:
pa->balance = -1;
leftsub->balance = 1;
pa = RotateRight(ptree, pa);
ret = false;
break;
case -1:
pa->balance = 0;
leftsub->balance = 0;
pa = RotateRight(ptree, pa);
ret = true;
break;
case 1:
rightsub = leftsub->rightchild;
switch (leftsub->balance)
{
case 0:
pa->balance = 0;
leftsub->balance = 0;
break;
case 1:
pa->balance = 0;
leftsub->balance = -1;
break;
case -1:
pa->balance = 1;
leftsub->balance = 0;
break;
}
rightsub->balance = 0;
RotateLeft(ptree, leftsub);
pa = RotateRight(ptree, pa);
ret = true;
break;
}
return ret;
}
bool Del_RightBalance(AVLTree* ptree, AVLNode*& pa)
{
assert(ptree != nullptr && pa != nullptr);
AVLNode* rightsub = pa->rightchild, * leftsub = nullptr;
bool ret = false;
switch (rightsub->balance)
{
case 0:
pa->balance = 1;
rightsub->balance = -1;
pa = RotateLeft(ptree, pa);
ret = false;
break;
case 1:
pa->balance = 0;
rightsub->balance = 0;
pa = RotateLeft(ptree, pa);
ret = true;
break;
case -1:
leftsub = rightsub->leftchild;
switch (leftsub->balance)
{
case 0:
pa->balance = 0;
rightsub->balance = 0;
break;
case 1:
pa->balance = - 1;
rightsub->balance = 0;
break;
case -1:
pa->balance = 0;
rightsub->balance = 1;
break;
}
leftsub->balance = 0;
RotateRight(ptree, rightsub);
pa = RotateLeft(ptree, pa);
ret = true;
break;
}
return ret;
}
void Adjust_Remove_Item(AVLTree *ptree, AVLNode *ptr,bool lefttag)
{
assert(ptr != nullptr && ptree != nullptr);
bool shorter = true;
AVLNode* pa = ptr->parent;
while (pa != nullptr && shorter)
{
if (lefttag)//pa->leftchild = ptr;
{
switch (pa->balance)
{
case 0:
pa->balance = -1;
shorter = false;
break;
case -1:
pa->balance = 0;
shorter = true;
break;
case 1:
shorter = Del_RightBalance(ptree, pa);
break;
}
}
else
{
switch (pa->balance)
{
case 0:
pa->balance = -1;
shorter = false;
break;
case 1:
pa->balance = 0;
shorter = true;
break;
case -1:
shorter = Del_LeftBalance(ptree, pa);
break;
}
}
ptr = pa;
pa = ptr->parent;
if( pa != nullptr)
{
lefttag = pa->leftchild == ptr ? true : false;
}
}
}
bool Remove_Item(AVLTree* ptree, const KeyType kx)
{
assert(ptree != nullptr);
if (ptree->root == nullptr) return false;
AVLNode* ptr = FindValue(ptree, kx);
bool lefttag = true;
if (ptr == nullptr) return false;
if (ptr->leftchild != nullptr && ptr->rightchild != nullptr)
{
AVLNode* subnode = Next(ptr);
ptr->key = subnode->key;
ptr = subnode;
}
AVLNode* child = ptr->leftchild != nullptr ? ptr->leftchild : ptr->rightchild;
AVLNode* pa = ptr->parent;
if(pa!=nullptr)
{
lefttag = pa->leftchild == ptr ? true : false;
}
if (child != nullptr) child->parent = pa;//说明ptr为单分支
if (pa != nullptr)//判断ptr是否为根
{
if (pa->leftchild == ptr)
{
pa->leftchild = child;
}
else
{
pa->rightchild = child;
}
}
else
{
ptree->root = child;
}
if (pa != nullptr && ptr != nullptr)
{
Adjust_Remove_Item(ptree, ptr, lefttag);
}
FreeNode(ptr);
ptree->cursize -= 1;
return true;
}
int main()
{
KeyType ar[] = { 16,3,7,11,9,26,18,14,15,45,34 };
int len = sizeof(ar) / sizeof(ar[0]);
AVLTree tree;
InitTree(&tree);
for (int i = 0; i < len; ++i)
{
Insert_Item(&tree, ar[i]);
}
NiceInOrder(&tree);
KeyType kx;
while (cin >> kx, kx != -1)
{
Remove_Item(&tree, kx);
NiceInOrder(&tree);
}
return 0;
}