您的位置:首页 > 编程语言 > C语言/C++

二叉搜索树的非递归C++实现

2012-10-29 22:15 134 查看
师兄的,学习了:/article/3505994.html

头文件:
/*****************************************************************************
*                                    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
= { 3, 1, 2, 7, 5, 8, 4, 6 };
int y
= { 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: