师兄的,学习了:http://my.oschina.net/zmjerry/blog/6041
头文件:
/***************************************************************************** * student.h * * A student class including comparison operators. * * Zhang Ming, 2009-10 *****************************************************************************/ #ifndef STUDENT_H #define STUDENT_H #include <iostream> #include <string> using namespace std; namespace itlab { class Student { public: Student() : key(0), firstName("Ming"), lastName("Zhang") { } Student( int number, const string &name1="Ming", const string &name2="Zhang" ) { key = number; firstName = name1; lastName = name2; } ~Student() { } inline void operator=( const Student &stu ) { key = stu.key; firstName = stu.firstName; lastName = stu.lastName; } inline bool operator<( const Student &stu ) { return key < stu.key; } inline bool operator>( const Student &stu ) { return key > stu.key; } inline bool operator==( const Student &stu ) { return key == stu.key; } friend istream& operator>>( istream &in, Student &stu ) { in >> stu.key >> stu.lastName >> stu.firstName; return in; } friend ostream& operator<<( ostream &out, Student &stu ) { out << stu.key << "\t" << stu.lastName << " " << stu.firstName << endl; return out; } int key; private: string firstName; string lastName; }; // class Student } // namespace itlab #endif // STUDENT_H
/***************************************************************************** * bstree.h * * Binary Search Tree * * This class provides "traversal(preorder,inorder or postorder), "search", * "insert" and "remove" operations for Binary Search Tree. * * All of the algorithms are implemented by the nonrecursion method. * * Zhang Ming, 20010-07 *****************************************************************************/ #ifndef BINARY_SEARCH_TREE_H #define BINARY_SEARCH_TREE_H #include <iostream> #include <stack.h> using namespace std; namespace itlab { /** * Node in Binary Search Tree */ template <typename Object> struct BSNode { Object data; BSNode<Object> *left, *right; BSNode() : left(NULL), right(NULL) { } BSNode( const Object &x, BSNode<Object> *lp=NULL, BSNode<Object> *rp=NULL ) { data = x; left = lp; right = rp; } bool operator<( BSNode<Object> &x ) { return data < x.data; } bool operator>( BSNode<Object> &x ) { return data > x.data; } bool operator==( BSNode<Object> &x ) { return data == x.data; } }; // struct BSNode template <typename Object, typename Key> class BSTree { public: BSTree(); ~BSTree(); // BSTree( const BSTree &rhs ); // BSTree & operator=( const BSTree &rhs ); bool isEmpty(); void makeEmpty(); void preTraverse(); void inTraverse(); void postTraverse(); bool insert( const Object &x ); bool remove( Key k ); BSNode<Object>* search( Key k ); Object minItem(); Object maxItem(); private: BSNode<Object> *root; void preTravNonrecursion( BSNode<Object> *t ); void inTravNonrecursion( BSNode<Object> *t ); void postTravNonrecursion( BSNode<Object> *t ); void destroy( BSNode<Object> *&r ); bool insert( BSNode<Object> *&r, const Object &x ); bool remove( BSNode<Object> *&r, Key k ); BSNode<Object>* search( BSNode<Object> *r, Key k ); BSNode<Object>* minItem( BSNode<Object> *r ); BSNode<Object>* maxItem( BSNode<Object> *r ); void visit( BSNode<Object> *p ); }; // class BSTree #include <bstree-impl.h> } // namespace itlab #endif // BINARY_SEARCH_TREE_H
实现文件:
/***************************************************************************** * bstree-impl.h * * Implementation for binary search rree. * * Zhang Ming, 2010-07 *****************************************************************************/ /** * constructors and destructor */ template <typename Object, typename Key> BSTree<Object, Key>::BSTree() : root(NULL) { } template <typename Object, typename Key> BSTree<Object, Key>::~BSTree() { destroy(root); } /** * If the tree is empty, return true. */ template <typename Object, typename Key> inline bool BSTree<Object, Key>::isEmpty() { return ( root == NULL ); } /** * Make the tree empty. */ template <typename Object, typename Key> inline void BSTree<Object, Key>::makeEmpty() { destroy( root ); } /** * preorder traversal */ template <typename Object, typename Key> inline void BSTree<Object, Key>::preTraverse() { preTravNonrecursion( root ); } /** * inorder traversal */ template <typename Object, typename Key> inline void BSTree<Object, Key>::inTraverse() { inTravNonrecursion( root ); } /** * postorder traversal */ template <typename Object, typename Key> inline void BSTree<Object, Key>::postTraverse() { postTravNonrecursion( root ); } /** * Insert a new element x in the tree. * If "x" isn't existent, return "true", else return "false". */ template <typename Object, typename Key> inline bool BSTree<Object, Key>::insert( const Object &x ) { return insert( root, x ); } /** * Delete the element x, which key is "k", in the tree. * If such key is existent, copy the deleted element to "x", * and return "true"; else return "false". */ template <typename Object, typename Key> inline bool BSTree<Object, Key>::remove( Key k ) { return remove( root, k ); } /** * Finding an element with key value of "k" in the tree. */ template <typename Object, typename Key> inline BSNode<Object>* BSTree<Object, Key>::search( Key k ) { return search( root, k ); } /** * Return smallest item in the tree. */ template <typename Object, typename Key> Object BSTree<Object, Key>::minItem() { return minItem(root)->data; } /** * Return largest item in the tree. */ template <typename Object, typename Key> Object BSTree<Object, Key>::maxItem() { return maxItem(root)->data; } /** * Destroy the tree. */ template <typename Object, typename Key> void BSTree<Object, Key>::destroy( BSNode<Object> *&r ) { if( r != NULL ) { destroy( r->left ); destroy( r->right ); delete r; } r = NULL; } /** * Preorder traversa the tree by nonrecursion method. */ template <typename Object, typename Key> void BSTree<Object, Key>::preTravNonrecursion( BSNode<Object> *t ) { Stack< BSNode<Object>* > s; while( (t != NULL) || !s.isEmpty() ) { if( t != NULL ) { visit( t ); s.push( t ); t = t->left; } else { s.getTop( t ); s.pop(); t = t->right; } } } /** * Inorder traversa the tree by nonrecursion method. */ template <typename Object, typename Key> void BSTree<Object, Key>::inTravNonrecursion( BSNode<Object> *t ) { Stack< BSNode<Object>* > s; while( (t != NULL) || !s.isEmpty() ) { if( t != NULL ) { s.push( t ); t = t->left; } else { s.getTop( t ); visit(t); s.pop(); t = t->right; } } } /** * Postorder traversa the tree by nonrecursion method. */ template <typename Object, typename Key> void BSTree<Object, Key>::postTravNonrecursion( BSNode<Object> *t ) { Stack< BSNode<Object>* > s; BSNode<Object> *pre = NULL, //last traversed node *top = NULL; //current traversed node while( (t != NULL) || !s.isEmpty() ) { if( t != NULL ) { s.push( t ); t = t->left; } else { s.getTop( top ); if( top->right != NULL && top->right != pre ) t = top->right; else { visit( top ); pre = top; s.pop(); } } } } /** * Insert elemetn "x" into the tree "r". */ template <typename Object, typename Key> bool BSTree<Object, Key>::insert( BSNode<Object> *&r, const Object &x ) { BSNode<Object> *cur = r, *par = NULL; while( cur != NULL ) { if( cur->data == x ) break; else { par = cur; if( cur->data < x ) cur = cur->right; else if( cur->data > x ) cur = cur->left; } } if( cur != NULL ) return false; else { BSNode<Object> *tmp = new BSNode<Object>( x, NULL, NULL ); if( par == NULL ) r = tmp; else { if( par->data < x ) par->right = tmp; else par->left = tmp; } return true; } } /** * Remove elemetn with key "k" from the tree "r". */ template <typename Object, typename Key> bool BSTree<Object, Key>::remove( BSNode<Object> *&r, Key k ) { if( r == NULL ) return false; if( k < r->data.key ) return remove( r->left, k ); else if( r->data.key < k ) return remove( r->right, k ); else if( r->left != NULL && r->right != NULL ) { r->data = minItem( r->right )->data; return remove( r->right, r->data.key ); } else { BSNode<Object> *oldNode = r; r = ( r->left != NULL ) ? r->left : r->right; delete oldNode; return true; } } /** * Remove elemetn with key "k" from the tree "r". */ template <typename Object, typename Key> BSNode<Object>* BSTree<Object, Key>::search( BSNode<Object> *r, Key k ) { while( r != NULL ) if( k < r->data.key ) r = r->left; else if( k > r->data.key ) r = r->right; else return r; return NULL; } /** * Find the smallest element in the tree "r". */ template <typename Object, typename Key> BSNode<Object>* BSTree<Object, Key>::minItem( BSNode<Object> *r ) { if( r == NULL ) return NULL; while( r->left != NULL ) r = r->left; return r; } /** * Find the maximum element in the tree "r". */ template <typename Object, typename Key> BSNode<Object>* BSTree<Object, Key>::maxItem( BSNode<Object> *r ) { if( r == NULL ) return NULL; while( r->right != NULL ) r = r->right; return r; } /** * Visit the item pointed by "p". */ template <typename Object, typename Key> void BSTree<Object, Key>::visit( BSNode<Object> *p ) { cout << p->data; }
测试文件:
/***************************************************************************** * bstree_test.cpp * * Binary search tree class testing. * * Zhang Ming, 2010-07 *****************************************************************************/ #include <iostream> #include <student.h> #include <bstree.h> using namespace std; using namespace itlab; int main() { const int N = 8, M = 4; int x[N] = { 3, 1, 2, 7, 5, 8, 4, 6 }; int y[N] = { 3, 2, 5, 7, 7, 9, 5, 0 }; int z[M] = { 3, 2, 1, 7 }; Student stu; BSNode<Student> *pNode = NULL; BSTree<Student, int> stuTree; for( int i=0; i<N; ++i ) { stu.key = x[i]; if( stuTree.insert( stu ) ) cout << "Insert " << x[i] << " success." << endl; else cout << "Insert failing." << endl; } cout << endl; cout << "Preorder Travesal: " << endl; stuTree.preTraverse(); cout << endl << "Inorder Travesal: " << endl; stuTree.inTraverse(); cout << endl << "Postorder Travesal: " << endl; stuTree.postTraverse(); cout << endl; for( int i=0; i<N; ++i ) { if( stuTree.remove( y[i] ) ) { cout << "Remove " << y[i] <<" sucess. Preorder Travesal: "<< endl; // stuTree.preTraverse(); stuTree.inTraverse(); // stuTree.postTraverse(); } else cout << "No such item (key=" << y[i] << ") in the tree!" << endl; } cout << endl; for( int i=0; i<M; ++i) { pNode = stuTree.search( z[i] ); if( pNode ) cout << "Finding the element: " << pNode->data; else cout << "No such item (key=" << z[i] << ") in the tree!" << endl; } cout << endl; stuTree.makeEmpty(); if( stuTree.isEmpty() ) cout << "The tree is empty." << endl; else cerr << "Making tree empty failing!" << endl; cout << endl; return 0; }