#include <stdio.h>
#include <vector>
#include <iostream>
using namespace std;
template<class elemType>
struct avlNode{
avlNode<elemType> *lLink;//left child node
avlNode<elemType> *rLink;//right child node
avlNode<elemType> *pLink;//point to parent node
elemType info;
int bfactor;
};
//rotate to left
template<class elemType>
void rotateToLeft(avlNode<elemType> *&root)
{
if(root == NULL)
{
cout << "root is null"<<endl;
}
if(root->rLink == NULL)
{
cout << "right child tree is null"<<endl;
}
avlNode<elemType> *pTmp = root->rLink;
root->rLink = pTmp->lLink;
if(root->rLink != NULL)
root->rLink->pLink = root;//set the parent link
pTmp->lLink = root;
pTmp->pLink = root->pLink;//set the parent link
if(pTmp->lLink != NULL)
pTmp->lLink->pLink = pTmp;//set the parent link
root = pTmp;
return;
}
//rotate to right
template<class elemType>
void rotateToRight(avlNode<elemType> *&root)
{
if(root == NULL)
{
cout << "root is null"<<endl;
}
if(root->lLink == NULL)
{
cout << "left child tree is null"<<endl;
}
avlNode<elemType> *pTmp = root->lLink;
root->lLink = pTmp->rLink;
if(root->lLink != NULL)
root->lLink->pLink = root;//set the parent link
pTmp->rLink = root;
pTmp->pLink = root->pLink;//set the parent link
if(pTmp->rLink != NULL)
pTmp->rLink->pLink = pTmp;//set the parent link
root = pTmp;
return;
}
//balance from left
template<class elemType>
void balanceFromLeft(avlNode<elemType> *&root)
{
avlNode<elemType> *pTmp1;
avlNode<elemType> *pTmp2;
pTmp1 = root->lLink;//pTmp1 pointing to the left subTree of root
switch(pTmp1->bfactor)
{
case -1:
{
root->bfactor = 0;
pTmp1->bfactor = 0;
rotateToRight(root);
}
break;
case 0:
{
printf("the bfactor is 0, so need not balance\n");
}
break;
case 1:
{
pTmp2 = pTmp1->rLink;
if(pTmp2 == NULL)
{
root->bfactor = 0;
pTmp1->bfactor = 0;
break;
}
switch(pTmp2->bfactor)
{
case -1:
{
root->bfactor = 1;
pTmp1->bfactor = 0;
}
break;
case 0:
{
root->bfactor = 0;
pTmp1->bfactor = -1;
}
break;
case 1:
{
root->bfactor = 0;
pTmp1->bfactor = -1;
}
break;
}
pTmp2->bfactor = 0;
rotateToLeft(pTmp1);
root->lLink = pTmp1;
rotateToRight(root);
}
break;
}
return ;
}
//balance from right
template<class elemType>
void balanceFromRight(avlNode<elemType> *&root)
{
avlNode<elemType> *pTmp1;
avlNode<elemType> *pTmp2;
pTmp1 = root->rLink;//pTmp1 pointing to the right subTree of root
switch(pTmp1->bfactor)
{
case -1:
{
pTmp2 = pTmp1->rLink;
if(pTmp2 == NULL)
{
root->bfactor = 0;
pTmp1->bfactor = 0;
break;
}
switch(pTmp2->bfactor)
{
case -1:
{
root->bfactor = 0;
pTmp1->bfactor = 1;
}
break;
case 0:
{
root->bfactor = 0;
pTmp1->bfactor = 0;
}
break;
case 1:
{
root->bfactor = -1;
pTmp1->bfactor = 0;
}
break;
}
pTmp2->bfactor = 0;
rotateToRight(pTmp1);
root->lLink = pTmp1;
rotateToLeft(root);
}
break;
case 0:
{
printf("the bfactor is 0, so need not balance\n");
}
break;
case 1:
{
root->bfactor = 0;
pTmp1->bfactor = 0;
rotateToLeft(root);
}
break;
}
return ;
}
//balance from right
template<class elemType>
void insertNode(avlNode<elemType> *&root, avlNode<elemType> *newNode, bool &isTaller)
{
if(root == NULL)
{
root = newNode;
isTaller = true;
}
else
{
printf("(%s(%d):%d %d\n", __FILE__, __LINE__, root->info, newNode->info);
if(root->info == newNode->info)
{
printf("err: the same node is already in the tree\n");
goto proc_over;
}
if(root->info > newNode->info) //goto the left sub tree
{
insertNode(root->lLink, newNode, isTaller);
if(isTaller)//the left sub tree height is increase
{
switch(root->bfactor)
{
case -1:
{
balanceFromLeft(root);
isTaller = false;
}
break;
case 0:
{
root->bfactor = -1;
break;
}
break;
case 1:
{
root->bfactor = 0;
isTaller =false;
}
break;
}
}
}
if(root->info < newNode->info) //goto the right sub tree
{
insertNode(root->rLink, newNode, isTaller);
if(isTaller)//the left sub tree height is increase
{
switch(root->bfactor)
{
case -1:
{
root->bfactor = 0;
isTaller =false;
}
break;
case 0:
{
root->bfactor = 1;
break;
}
break;
case 1:
{
balanceFromRight(root);
isTaller = false;
}
break;
}
}
}
}
proc_over:
return;
}
template<class elemType>
int traverseTree(avlNode<elemType> *root)
{
if(root != NULL)
{
if(root->lLink)
{
traverseTree(root->lLink);
}
printf(" %d\n", root->info);
if(root->rLink)
{
traverseTree(root->rLink);
}
}
return 0;
}
int main()
{
vector<int> A;
A.resize(14);
avlNode<int> *tree = NULL;
A ={27, 17, 3, 16, 13, 10, 1, 5, 7, 12, 4, 8, 9, 0};
for(auto entry:A)
{
cout << entry<<endl;
}
printf("**************************\n");
for(auto entry:A)
{
avlNode<int> *newNode = new avlNode<int>;
newNode->info = entry;
newNode->lLink = NULL;
newNode->rLink = NULL;
newNode->bfactor = 0;
bool isTaller = false;
insertNode(tree, newNode, isTaller);
}
traverseTree(tree);
printf("**************************\n");
return 0;
}