AVL树作为一个比较简单和基础的自调整二叉树,其重要性不言而喻。
经过学习后,写出以下比较精简的算法,含测试代码。
#include<iostream> #include<set> #include<ctime> using namespace std; typedef struct _Node{ int Value , Balance; struct _Node *Left , *Right;}Node,*BinaryTree; void InitTree( BinaryTree & a ); bool Search( BinaryTree & a , int target ); bool Delete( BinaryTree & a , int target , bool & ); bool Insert( BinaryTree & a , int target , bool & ); void Debug( int n ) { int ceshi[3] = { 2 , 2 , 4 }; int total = ceshi[0] + ceshi[1] + ceshi[2]; bool mid2; set<int> a; BinaryTree b; InitTree( b ); srand(time(0)); for( int i = 0 ; i != n ; ++i ) { int mid = rand()%total ; if( mid < ceshi[0] ) mid = 1; else if( mid < ceshi[0] + ceshi[1] ) mid = 2; else mid = 3; int target = rand() % 100; //cout<<“调试 “<<mid<<” “<<target<<endl; if( mid == 1 ) { if( Search( b , target ) != ( a.find( target ) != a.end() ) ) { cout<<“出错!”<<endl; system(“pause”); } } else if( mid == 2 ) { if( Insert( b , target ,mid2) != ( a.insert( target ).second ) ) { cout<<“出错!”<<endl; system(“pause”); } } else if( mid == 3 ) { if( Delete( b , target ,mid2) != ( a.erase( target ) != 0 )) { cout<<“出错! “<<endl; system(“pause”); } } } } int main() { while( 1 ) { //cout<<endl<<endl<<“分界线”<<endl<<endl; int begin = clock(); Debug( 1000000 ); cout<<“恭喜,测试通过,测试时间为:”<<clock() – begin<< endl; } return 0; BinaryTree a; InitTree( a ); bool mid2; while( 1 ) { int mid,target; cout<<“输入操作 “<<endl <<“1 — 查找”<<endl <<“2 — 插入”<<endl <<“3 — 删除”<<endl; cin>>mid; cout<<“输入目标: “;cin>>target; if( mid == 1 ) cout<<“查找结果: “<<Search( a , target ) <<endl; else if( mid == 2 ) cout<<“插入结果: “<<Insert( a , target ,mid2) <<endl; else if( mid == 3 ) cout<<“删除结果:”<<Delete( a , target ,mid2) <<endl; } return 0; } void InitTree( BinaryTree & a ) { a = NULL; } bool Search( BinaryTree & a , int target ) { if( a == NULL ) return false; else if( a->Value == target ) return true; else if( a->Value < target ) return Search( a->Right , target ); else return Search( a->Left , target ); } void L_Roate( Node *& a ) { Node * p = a->Right; a->Right = p->Left; p->Left = a; a = p; } void R_Roate( Node *& a ) { Node * p = a->Left ; a->Left = p->Right; p->Right = a; a = p; } void LeftBalance( Node * & a ) { Node *p = a->Left,*q; bool IsChange = true; switch( p->Balance ) { case 1: a->Balance = p->Balance = 0;R_Roate( a );break; case 0: a->Balance = 1;p->Balance = -1;R_Roate( a ); break; case -1: q = p->Right; switch( q->Balance ) { case 1:p->Balance = 0 ; a->Balance = -1 ;break; case -1:p->Balance = 1 ; a->Balance = 0 ;break; case 0:p->Balance = 0 ; a->Balance = 0 ;break; } q->Balance = 0 ; L_Roate( a->Left ); R_Roate( a ); } } void RightBalance( Node * & a ) { Node *p = a->Right ,*q ; switch( p->Balance ) { case -1: a->Balance = p->Balance = 0 ;L_Roate( a ); break; case 0: a->Balance = -1 ; p->Balance = 1 ; L_Roate( a ) ; break; case 1: q = p->Left; switch( q->Balance ) { case -1:p->Balance = 0 ; a->Balance = 1 ;break; case 1:p->Balance = -1 ; a->Balance = 0 ; break; case 0:p->Balance = 0 ; a->Balance = 0 ; break; } q->Balance = 0 ; R_Roate( a->Right ); L_Roate( a ); } } bool Insert( BinaryTree & a , int target , bool& taller ) { bool result; if( a == NULL ) { a = new Node ;a->Balance = 0 ; a->Left = a->Right = NULL; a->Value = target ; taller = true;result = true; } else if( a->Value == target ) { result = false ; taller = false;} else if( a->Value < target ) { result = Insert( a->Right , target , taller ); if( taller ) { –a->Balance; if( a->Balance == -2 ) RightBalance( a ); taller = ( a->Balance != 0 ) ; } } else { result = Insert( a->Left , target , taller ); if( taller ) { ++a->Balance; if( a->Balance == 2 ) LeftBalance( a ); taller = ( a->Balance != 0 ) ; } } return result; } bool NtDelete( Node * & a ) { Node *p; if( a->Left == NULL ) { p = a ; a = p->Right ; delete p ; return false ;} else if( a->Right == NULL ) { p = a ; a = p->Left ; delete p ; return false ;} else { p = a->Left ; while( p->Right ) p = p->Right ; a->Value = p->Value; return true; } } bool Delete( BinaryTree & a , int target , bool & shorter ) { bool result; if( a == NULL ) { result = false ; shorter = false; } else if( a->Value == target ) { if( NtDelete( a ) ) { target = a->Value ;goto MM; } else {result = true ; shorter = true; } } else if( a->Value < target ) { result = Delete( a->Right ,target , shorter ); if( shorter ) { ++a->Balance; if( a->Balance == 2 ) LeftBalance( a ); shorter = ( a->Balance == 0 ); } } else { MM: result = Delete( a->Left , target, shorter ); if( shorter ) { –a->Balance; if( a->Balance == -2 ) RightBalance( a ); shorter = ( a->Balance == 0 ); } } return result; }