升级版的二叉搜索树,插入和删除时要注意调整平衡。
#ifndef avlTree_H_
#define avlTree_H_
#include <iostream>
using namespace std;
class treeNode
{
public:
treeNode():lchild(NULL),rchild(NULL),height(1),freq(1){}
int data;
treeNode*lchild;
treeNode*rchild;
int height;
unsigned int freq;//frequency
};
class avlTree
{
public:
//interface
avlTree():root(NULL){}
void insert(int x);
treeNode *find(int x);
void deletex(int x);
void inOrderTraversal();
private:
treeNode *root;
void insertHelp(treeNode *&node,int x);
treeNode *findHelp(treeNode*node,int x);
void inOrderHelp(const treeNode *node);
void deleteHelp(treeNode *&node,int x);
int height(treeNode *node);
void singRotateLeft(treeNode *&k2);
void singRotateRight(treeNode *&k2);
void doubleRotateLR(treeNode *&k3);
void doubleRotateRL(treeNode *&k3);
int max(int a,int b);
};
int avlTree::height(treeNode *node)
{
if(node!=NULL)
return node->height;
else
return 0;
}
int avlTree::max(int a,int b)
{
return a>b?a:b;
}
//LL->right
void avlTree::singRotateRight(treeNode *&k2)
{
treeNode *k1;
k1=k2->lchild;
k2->lchild=k1->rchild;
k1->rchild=k2;
k2->height=max(height(k2->lchild),height(k2->rchild))+1;
k1->height=max(height(k1->lchild),k2->height)+1;
// root=k1;
treeNode*temp =k2;
k2=k1;
k1=temp;
}
//RR->left
void avlTree::singRotateLeft(treeNode *&k2)
{
treeNode *k1;
k1=k2->rchild;
k2->rchild=k1->lchild;
k1->lchild=k2;
k2->height=max(height(k2->lchild),height(k2->rchild))+1;
k1->height=max(height(k1->rchild),k2->height)+1;
// root=k1;
treeNode*temp =k2;
k2=k1;
k1=temp;
}
//LR->left->right
void avlTree::doubleRotateLR(treeNode *&k3)
{
singRotateLeft(k3->lchild);
singRotateRight(k3);
}
//RL->right->left
void avlTree::doubleRotateRL(treeNode *&k3)
{
singRotateRight(k3->rchild);
singRotateLeft(k3);
}
void avlTree::insertHelp(treeNode *&node,int x)
{
if(node==NULL)
{
node=new treeNode;
node->data=x;
return;
}
if(node->data>x)
{
insertHelp(node->lchild,x);
if(height(node->lchild)-height(node->rchild)==2)
{
if(x<node->lchild->data)
singRotateRight(node);
else
doubleRotateLR(node);
}
}
else if(node->data<x)
{
insertHelp(node->rchild,x);
// cout<<height(node->rchild)<<" "<<height(node->lchild)<<endl;
if(height(node->rchild)-height(node->lchild)==2)
{
if(x>node->rchild->data)
singRotateLeft(node);
else
doubleRotateRL(node);
}
}
else ++(node->freq);
node->height=max(height(node->lchild),height(node->rchild))+1;
}
void avlTree::insert(int x)
{
insertHelp(root,x);
}
treeNode* avlTree::findHelp(treeNode*node,int x)
{
if(node==NULL)return NULL;
if(node->data>x)
{
return findHelp(node->lchild,x);
}
else if(node->data<x)
{
return findHelp(node->rchild,x);
}
else return node;
}
treeNode*avlTree::find(int x)
{
return findHelp(root,x);
}
void avlTree::inOrderHelp(const treeNode*node)
{
if(node==NULL)return;
inOrderHelp(node->lchild);
cout<<node->data<<" ";
inOrderHelp(node->rchild);
}
void avlTree::inOrderTraversal()
{
inOrderHelp(root);
}
void avlTree::deleteHelp(treeNode*&node,int x)
{
if(node==NULL)return;
if(x<node->data)
{
deleteHelp(node->lchild,x);
if(height(node->rchild)-height(node->lchild)==2)
{
if(node->rchild->lchild!=NULL &&(height(node->rchild->lchild)>height(node->rchild->rchild)))
doubleRotateRL(node);
else
singRotateLeft(node);
}
}
else if(x>node->data)
{
deleteHelp(node->rchild,x);
if(height(node->lchild)-height(node->rchild)==2)
{
if(node->lchild->rchild!=NULL && (height(node->lchild->rchild)>height(node->lchild->lchild)))
doubleRotateLR(node);
else
singRotateRight(node);
}
}
else
{
if(node->lchild&&node->rchild)
{
treeNode*temp=node->rchild;
while(temp->lchild!=NULL)
temp=temp->lchild;//找到右子树中值最小的节点
node->data=temp->data;
node->freq=temp->freq;
deleteHelp(node->rchild,temp->data);
if(height(node->lchild)-height(node->rchild)==2)
{
if(node->lchild->rchild && (height(node->lchild->rchild)>height(node->lchild->lchild)))
doubleRotateLR(node);
else
singRotateRight(node);
}
}
else
{
treeNode*temp=node;
if(node->lchild==NULL)
node=node->rchild;
else if(node->rchild==NULL)
node=node->lchild;
delete(temp);
temp=NULL;
}
}
if(node==NULL)return;
node->height=max(height(node->lchild),height(node->rchild))+1;
return;
}
void avlTree::deletex(int x)
{
deleteHelp(root,x);
}
#endif
测试:
#include <iostream>
#include "avlTree.h"
using namespace std;
int main()
{
avlTree test;
test.insert(25);
test.insert(27);
test.insert(30);
test.insert(12);
test.insert(11);
test.insert(18);
test.insert(14);
test.insert(20);
test.insert(15);
test.insert(22);
test.inOrderTraversal();
cout<<endl;
// cout<<test.find(20)->data;
cout<<endl;
test.deletex(18);
test.inOrderTraversal();
return 0;
}