33,008
社区成员
发帖
与我相关
我的任务
分享
#include <iostream>
using namespace std;
template<class T>
struct Node
{
public:
Node(T d)
{
data = d;
P = NULL;
L = NULL;
R = NULL;
balan = 0;
}
T data;
Node* P;
Node* L;
Node* R;
friend ostream& operator << (ostream& os, Node<T> * node)
{
os<<node->data;
return os;
}
int balan;
};
template<class T>
class AVLTree
{
public:
AVLTree():head(NULL)
{
}
void Insert(T value);
bool Search(T value, Node<T>** pNode);
void Delete(T value);
Node<T>* PreNode(Node<T>* cur);
Node<T>* NextNode(Node<T>* cur);
void AdjustAvl(Node<T>* pNode, Node<T>* cur);
void Print();
private:
void SwapLRRL(Node<T>* pNode, Node<T>* cur);
void SwapLLRR(Node<T>* pNode, Node<T>* cur);
void SwapNode(Node<T>* dNode, Node<T>* tNode);
private:
Node<T>* head;
};
template<class T>
void AVLTree<T>::SwapNode(Node<T>* dNode, Node<T>* tNode)
{
if(tNode == NULL || dNode==NULL) return ;
T tmp = dNode->data;
dNode->data = tNode->data;
tNode->data = tmp;
}
template<class T>
void AVLTree<T>::SwapLRRL(Node<T>* pNode, Node<T>* cur)
{
cur->P = pNode->P;
if(pNode->P != NULL)
{
if(pNode->P->L = pNode)
pNode->P->L = cur;
else
pNode->P->R = cur;
}
pNode->P = cur;
pNode->balan = cur->balan;
if(pNode->R == cur)
{
pNode->R = cur->L;
if(cur->L != NULL) cur->L->P = pNode;
cur->L = pNode;
cur->balan = 1;
}
else
{
pNode->L = cur->R;
if(cur->R != NULL) cur->R->P = pNode;
cur->R = pNode;
cur->balan = -1;
}
}
template<class T>
void AVLTree<T>::SwapLLRR(Node<T>* pNode, Node<T>* cur)
{
cur->P = pNode->P;
if(pNode->P != NULL)
{
if(pNode->P->L == pNode) pNode->P->L = cur;
else pNode->P->R = cur;
}
else
{
head = cur;
}
pNode->P = cur;
if(pNode->L == cur)
{
pNode->L = cur->R;
if(cur->R != NULL) cur->R->P = pNode;
cur->R = pNode;
}
else
{
pNode->R = cur->L;
if(cur->L != NULL) cur->L->P = pNode;
cur->L = pNode;
}
}
template<class T>
void AVLTree<T>::AdjustAvl(Node<T>* pNode, Node<T>* cur)
{
switch(pNode->balan)
{
case 2:
if(cur->balan == -1)
{
SwapLRRL(cur, cur->R);
cur = pNode->L;
}
SwapLLRR(pNode, cur);
break;
case -2:
if(cur->balan == 1)
{
SwapLLRR(cur, cur->L);
cur = pNode->R;
}
SwapLLRR(pNode, cur);
break;
}
pNode->balan = 0;
cur->balan = 0;
}
template<class T>
void AVLTree<T>::Insert(T value)
{
if(head == NULL)
{
head = new Node<T>(value);
return ;
}
Node<T> *pNode;
if(Search(value, &pNode)) return ;
Node<T> *tNode = new Node<T>(value);
tNode->P = pNode;
if(pNode->data > tNode->data) pNode->L = tNode;
else pNode->R = tNode;
while(pNode != NULL)
{
if(tNode == pNode->L)
{
if(pNode->balan == 1)
{
pNode->balan = 2;
break;
}
else if(pNode->balan == -1)
{
pNode->balan = 0;
break;
}
else
{
pNode->balan = 1;
tNode = pNode;
pNode = pNode->P;
}
}
else
{
if(pNode->balan == 1)
{
pNode->balan = 0;
break;
}
else if(pNode->balan == -1)
{
pNode->balan = -2;
break;
}
else
{
pNode->balan = -1;
tNode = pNode;
pNode = pNode->P;
}
}
}
if(pNode != NULL) AdjustAvl(pNode, tNode);
}
template<class T>
bool AVLTree<T>::Search(T value, Node<T>** pNode)
{
Node<T>* tmp = head;
while(tmp != NULL)
{
*pNode = tmp;
if(tmp->data > value)
{
tmp = tmp->L;
}
else if(tmp->data < value)
{
tmp = tmp->R;
}
else
{
*pNode = tmp->P;
return true;
}
}
return false;
}
template<class T>
void AVLTree<T>::Delete(T value)
{
Node<T>* pNode;
Node<T>* cur;
Node<T>* dNode;
if(!Search(value, &pNode)) return ;
if(pNode == NULL)
{
dNode = head;
if(dNode->L == NULL && dNode->R == NULL)
{delete head; head = NULL; return ;}
}
else if(pNode->data > value) dNode = pNode->L;
else dNode = pNode->R;
if(dNode->balan == 1) cur = PreNode(dNode);
else if(dNode->balan == -1) cur = NextNode(dNode);
else
{
if(dNode->L == NULL)
cur = dNode;
else cur = PreNode(dNode);
}
if(cur == NULL) cur = dNode;
else SwapNode(dNode, cur);
pNode = cur->P;
//delete node
if(cur == pNode->L)
{
if(cur->R != NULL)cur->R->P = pNode;
pNode->L = cur->R;
delete cur;
cur = pNode->R;
}
else
{
if(cur->L != NULL)cur->L->P = pNode;
pNode->R = cur->L;
delete cur;
cur = pNode->L;
}
//find the nearest tree that need to be adjust
while(pNode != NULL)
{
if(pNode->balan == 0)
{
if(cur == pNode->R) pNode->balan = -1;
else pNode->balan = 1;
break;
}
else if(pNode->balan == 1)
{
if(cur == pNode->R)
pNode->balan = 0;
else {pNode->balan = 2; break;}
}
else
{
if(cur == pNode->L)
pNode->balan = 0;
else {pNode->balan = -2; break;}
}
cur = pNode;
pNode = pNode->P;
}
if(pNode != NULL) AdjustAvl(pNode, cur);
}
template<class T>
Node<T>* AVLTree<T>::PreNode(Node<T>* cur)
{
while(cur != NULL && cur->L != NULL)
{
cur = cur->L;
}
return cur;
}
template<class T>
Node<T>* AVLTree<T>::NextNode(Node<T>* cur)
{
if(cur->R == NULL)
{
if(cur->P == NULL) return NULL;
while(cur->P != NULL && cur == cur->P->R)
cur = cur->P;
return cur->P;
}
cur = cur->R;
while(cur != NULL && cur->L != NULL)
{
cur = cur->L;
}
return cur;
}
template<class T>
void AVLTree<T>::Print()
{
Node<T>* tmp = head;
if(tmp == NULL) return ;
while(tmp->L != NULL)
tmp = tmp->L;
cout<<tmp->data<<endl;
while((tmp=NextNode(tmp)) != NULL)
cout<<tmp->data<<endl;
}
int main()
{
AVLTree<int> avl;
avl.Insert(1);
avl.Insert(2);
avl.Insert(3);
avl.Insert(4);
avl.Insert(5);
avl.Insert(6);
avl.Insert(7);
avl.Delete(7);
avl.Print();
return 0;
}