实现:
1 #ifndef AVL_TREE_H 2 #define AVL_TREE_H 3 4 #include "dsexceptions.h" 5 #include <iostream> // For NULL 6 using namespace std; 7 8 // AvlTree class 9 // 10 // CONSTRUCTION: with ITEM_NOT_FOUND object used to signal failed finds 11 // 12 // ******************PUBLIC OPERATIONS********************* 13 // void insert( x ) --> Insert x 14 // void remove( x ) --> Remove x (unimplemented) 15 // bool contains( x ) --> Return true if x is present 16 // Comparable findMin( ) --> Return smallest item 17 // Comparable findMax( ) --> Return largest item 18 // boolean isEmpty( ) --> Return true if empty; else false 19 // void makeEmpty( ) --> Remove all items 20 // void printTree( ) --> Print tree in sorted order 21 // ******************ERRORS******************************** 22 // Throws UnderflowException as warranted 23 24 template <typename Comparable> 25 class AvlTree 26 { 27 public: 28 AvlTree( ) : root( NULL ) 29 { } 30 AvlTree( const AvlTree & rhs ) : root( NULL ) 31 { 32 *this = rhs; 33 } 34 35 ~AvlTree( ) 36 { 37 makeEmpty( ); 38 } 39 40 /** 41 * Find the smallest item in the tree. 42 * Throw UnderflowException if empty. 43 */ 44 const Comparable & findMin( ) const 45 { 46 if( isEmpty( ) ) 47 throw UnderflowException( ); 48 return findMin( root )->element; 49 } 50 51 /** 52 * Find the largest item in the tree. 53 * Throw UnderflowException if empty. 54 */ 55 const Comparable & findMax( ) const 56 { 57 if( isEmpty( ) ) 58 throw UnderflowException( ); 59 return findMax( root )->element; 60 } 61 62 /** 63 * Returns true if x is found in the tree. 64 */ 65 bool contains( const Comparable & x ) const 66 { 67 return contains( x, root ); 68 } 69 70 /** 71 * Test if the tree is logically empty. 72 * Return true if empty, false otherwise. 73 */ 74 bool isEmpty( ) const 75 { 76 return root == NULL; 77 } 78 79 /** 80 * Print the tree contents in sorted order. 81 */ 82 void printTree( ) const 83 { 84 if( isEmpty( ) ) 85 cout << "Empty tree" << endl; 86 else 87 printTree( root ); 88 } 89 90 /** 91 * Make the tree logically empty. 92 */ 93 void makeEmpty( ) 94 { 95 makeEmpty( root ); 96 } 97 98 /** 99 * Insert x into the tree; duplicates are ignored. 100 */ 101 void insert( const Comparable & x ) 102 { 103 insert( x, root ); 104 } 105 106 /** 107 * Remove x from the tree. Nothing is done if x is not found. 108 */ 109 void remove( const Comparable & x ) 110 { 111 cout << "Sorry, remove unimplemented; " << x << 112 " still present" << endl; 113 } 114 115 /** 116 * Deep copy. 117 */ 118 const AvlTree & operator=( const AvlTree & rhs ) 119 { 120 if( this != &rhs ) 121 { 122 makeEmpty( ); 123 root = clone( rhs.root ); 124 } 125 return *this; 126 } 127 128 private: 129 struct AvlNode 130 { 131 Comparable element; 132 AvlNode *left; 133 AvlNode *right; 134 int height; 135 136 AvlNode( const Comparable & theElement, AvlNode *lt, 137 AvlNode *rt, int h = 0 ) 138 : element( theElement ), left( lt ), right( rt ), height( h ) { } 139 }; 140 141 AvlNode *root; 142 143 144 /** 145 * Internal method to insert into a subtree. 146 * x is the item to insert. 147 * t is the node that roots the subtree. 148 * Set the new root of the subtree. 149 */ 150 void insert( const Comparable & x, AvlNode * & t ) 151 { 152 if( t == NULL ) 153 t = new AvlNode( x, NULL, NULL ); 154 else if( x < t->element ) 155 { 156 insert( x, t->left ); 157 if( height( t->left ) - height( t->right ) == 2 ) 158 if( x < t->left->element ) 159 rotateWithLeftChild( t ); 160 else 161 doubleWithLeftChild( t ); 162 } 163 else if( t->element < x ) 164 { 165 insert( x, t->right ); 166 if( height( t->right ) - height( t->left ) == 2 ) 167 if( t->right->element < x ) 168 rotateWithRightChild( t ); 169 else 170 doubleWithRightChild( t ); 171 } 172 else 173 ; // Duplicate; do nothing 174 t->height = max( height( t->left ), height( t->right ) ) + 1; 175 } 176 177 /** 178 * Internal method to find the smallest item in a subtree t. 179 * Return node containing the smallest item. 180 */ 181 AvlNode * findMin( AvlNode *t ) const 182 { 183 if( t == NULL ) 184 return NULL; 185 if( t->left == NULL ) 186 return t; 187 return findMin( t->left ); 188 } 189 190 /** 191 * Internal method to find the largest item in a subtree t. 192 * Return node containing the largest item. 193 */ 194 AvlNode * findMax( AvlNode *t ) const 195 { 196 if( t != NULL ) 197 while( t->right != NULL ) 198 t = t->right; 199 return t; 200 } 201 202 203 /** 204 * Internal method to test if an item is in a subtree. 205 * x is item to search for. 206 * t is the node that roots the tree. 207 */ 208 bool contains( const Comparable & x, AvlNode *t ) const 209 { 210 if( t == NULL ) 211 return false; 212 else if( x < t->element ) 213 return contains( x, t->left ); 214 else if( t->element < x ) 215 return contains( x, t->right ); 216 else 217 return true; // Match 218 } 219 /****** NONRECURSIVE VERSION************************* 220 bool contains( const Comparable & x, AvlNode *t ) const 221 { 222 while( t != NULL ) 223 if( x < t->element ) 224 t = t->left; 225 else if( t->element < x ) 226 t = t->right; 227 else 228 return true; // Match 229 230 return false; // No match 231 } 232 *****************************************************/ 233 234 /** 235 * Internal method to make subtree empty. 236 */ 237 void makeEmpty( AvlNode * & t ) 238 { 239 if( t != NULL ) 240 { 241 makeEmpty( t->left ); 242 makeEmpty( t->right ); 243 delete t; 244 } 245 t = NULL; 246 } 247 248 /** 249 * Internal method to print a subtree rooted at t in sorted order. 250 */ 251 void printTree( AvlNode *t ) const 252 { 253 if( t != NULL ) 254 { 255 printTree( t->left ); 256 cout << t->element << endl; 257 printTree( t->right ); 258 } 259 } 260 261 /** 262 * Internal method to clone subtree. 263 */ 264 AvlNode * clone( AvlNode *t ) const 265 { 266 if( t == NULL ) 267 return NULL; 268 else 269 return new AvlNode( t->element, clone( t->left ), clone( t->right ), t->height ); 270 } 271 // Avl manipulations 272 /** 273 * Return the height of node t or -1 if NULL. 274 */ 275 int height( AvlNode *t ) const 276 { 277 return t == NULL ? -1 : t->height; 278 } 279 280 int max( int lhs, int rhs ) const 281 { 282 return lhs > rhs ? lhs : rhs; 283 } 284 285 /** 286 * Rotate binary tree node with left child. 287 * For AVL trees, this is a single rotation for case 1. 288 * Update heights, then set new root. 289 */ 290 void rotateWithLeftChild( AvlNode * & k2 ) 291 { 292 AvlNode *k1 = k2->left; 293 k2->left = k1->right; 294 k1->right = k2; 295 k2->height = max( height( k2->left ), height( k2->right ) ) + 1; 296 k1->height = max( height( k1->left ), k2->height ) + 1; 297 k2 = k1; 298 } 299 300 /** 301 * Rotate binary tree node with right child. 302 * For AVL trees, this is a single rotation for case 4. 303 * Update heights, then set new root. 304 */ 305 void rotateWithRightChild( AvlNode * & k1 ) 306 { 307 AvlNode *k2 = k1->right; 308 k1->right = k2->left; 309 k2->left = k1; 310 k1->height = max( height( k1->left ), height( k1->right ) ) + 1; 311 k2->height = max( height( k2->right ), k1->height ) + 1; 312 k1 = k2; 313 } 314 315 /** 316 * Double rotate binary tree node: first left child. 317 * with its right child; then node k3 with new left child. 318 * For AVL trees, this is a double rotation for case 2. 319 * Update heights, then set new root. 320 */ 321 void doubleWithLeftChild( AvlNode * & k3 ) 322 { 323 rotateWithRightChild( k3->left ); 324 rotateWithLeftChild( k3 ); 325 } 326 327 /** 328 * Double rotate binary tree node: first right child. 329 * with its left child; then node k1 with new right child. 330 * For AVL trees, this is a double rotation for case 3. 331 * Update heights, then set new root. 332 */ 333 void doubleWithRightChild( AvlNode * & k1 ) 334 { 335 rotateWithLeftChild( k1->right ); 336 rotateWithRightChild( k1 ); 337 } 338 }; 339 340 #endif
测试:
1 #include <iostream> 2 #include "AvlTree.h" 3 using namespace std; 4 5 // Test program 6 int main( ) 7 { 8 AvlTree<int> t, t2; 9 int NUMS = 400000; 10 const int GAP = 37; 11 int i; 12 13 cout << "Checking... (no more output means success)" << endl; 14 15 for( i = GAP; i != 0; i = ( i + GAP ) % NUMS ) 16 t.insert( i ); 17 18 if( NUMS < 40 ) 19 t.printTree( ); 20 if( t.findMin( ) != 1 || t.findMax( ) != NUMS - 1 ) 21 cout << "FindMin or FindMax error!" << endl; 22 23 t2 = t; 24 25 for( i = 1; i < NUMS; i++ ) 26 if( !t2.contains( i ) ) 27 cout << "Find error1!" << endl; 28 if( t2.contains( 0 ) ) 29 cout << "ITEM_NOT_FOUND failed!" << endl; 30 31 cout << "Test finished" << endl; 32 return 0; 33 }