Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <assert.h>
- #include <iostream>
- #include <string>
- using std::string;
- class CAVLTree {
- public:
- CAVLTree() : root( 0 ) {}
- ~CAVLTree() { clear( root ); }
- bool Has( const string& key ) const;
- bool Add( const string& key );
- bool Remove( const string& key ) { return false; }
- private:
- // Узел дерева.
- struct CAVLNode {
- string Key;
- CAVLNode* Left;
- CAVLNode* Right;
- int Depth;
- explicit CAVLNode( const string& key ) : Key( key ), Left( 0 ), Right( 0 ), Depth( 1 ) {}
- };
- CAVLNode* root;
- void clear( CAVLNode* node );
- bool add( CAVLNode*& node, const string& key );
- void balance( CAVLNode*& node );
- static int depth( CAVLNode* node );
- static void rotateLeft( CAVLNode*& node );
- static void rotateRight( CAVLNode*& node );
- static void fixDepth( CAVLNode* node );
- };
- // Рекурсивная очистка всего поддерева.
- void CAVLTree::clear( CAVLNode* node )
- {
- if( node == 0 ) {
- return;
- }
- clear( node->Left );
- clear( node->Right );
- delete node;
- }
- bool CAVLTree::Has( const string& key ) const
- {
- CAVLNode* node = root;
- while( node != 0 ) {
- if( node->Key == key ) {
- return true;
- }
- node = node->Key < key ? node->Right : node->Left;
- }
- return false;
- }
- bool CAVLTree::Add( const string& key )
- {
- return add( root, key );
- }
- // Добавление ключа. Если ключ уже есть, вернет false.
- // Иначе добавит ключ, сделает балансировку во всем поддереве на пути до добавленного элемента.
- bool CAVLTree::add( CAVLNode*& node, const string& key )
- {
- if( node == 0 ) {
- node = new CAVLNode( key );
- return true;
- }
- if( node->Key == key ) {
- return false;
- }
- if( node->Key < key ) {
- add( node->Right, key );
- }
- //...
- return true;
- }
- void CAVLTree::balance( CAVLNode*& node )
- {
- const int bFactor = depth( node->Left ) - depth( node->Right );
- if( bFactor == -2 ) {
- const int rightBFactor = depth( node->Right->Left ) - depth( node->Right->Right );
- if( rightBFactor == 1 ) {
- rotateRight( node->Right );
- }
- rotateLeft( node );
- } else if( bFactor == 2 ) {
- const int leftBFactor = depth( node->Left->Left ) - depth( node->Left->Right );
- if( leftBFactor == -1 ) {
- rotateLeft( node->Left );
- }
- rotateRight( node );
- } else {
- fixDepth( node );
- }
- }
- int CAVLTree::depth( CAVLNode* node )
- {
- return node == 0 ? 0 : node->Depth;
- }
- // Левый поворот.
- void CAVLTree::rotateLeft( CAVLNode*& node )
- {
- assert( node != 0 );
- assert( node->Right != 0 );
- CAVLNode* right = node->Right;
- node->Right = right->Left;
- right->Left = node;
- node = right;
- fixDepth( node->Left );
- fixDepth( node );
- }
- // Правый поворот.
- void CAVLTree::rotateRight( CAVLNode*& node )
- {
- assert( node != 0 );
- assert( node->Left != 0 );
- CAVLNode* left = node->Left;
- node->Left = left->Right;
- left->Right = node;
- node = left;
- fixDepth( node->Right );
- fixDepth( node );
- }
- // Восстановить глубину в узле node по дочерним.
- void CAVLTree::fixDepth( CAVLNode* node )
- {
- assert( node != 0 );
- node->Depth = std::max( depth( node->Left ), depth( node->Right ) ) + 1;
- }
- int main()
- {
- CAVLTree tree;
- while( true ) {
- char command = 0;
- string value;
- std::cin >> command >> value;
- if( std::cin.fail() ) {
- break;
- }
- switch( command ) {
- case '?':
- std::cout << ( tree.Has( value ) ? "OK" : "FAIL" ) << std::endl;
- break;
- case '+':
- std::cout << ( tree.Add( value ) ? "OK" : "FAIL" ) << std::endl;
- break;
- case '-':
- std::cout << ( tree.Remove( value ) ? "OK" : "FAIL" ) << std::endl;
- break;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement