-BinarySearchTree.h
#ifndef __BINARY_SEARCH_TREE_H__
#define __BINARY_SEARCH_TREE_H__
#include <iostream>
#include <string>
template <class Object, class Comparator = std::less<Object> >
class BinarySearchTree {
public:
BinarySearchTree();
BinarySearchTree(const BinarySearchTree& rhs);
~BinarySearchTree();
const Object& findMin()const;
const Object& findMax()const;
bool contains(const Object& x)const;
bool isEmpty()const { return NULL == root; }
void printTree()const;
void makeEmpty();
void insert(const Object& x);
void remove(const Object& x);
const BinarySearchTree& operator=(const BinarySearchTree& rhs);
private:
struct BinaryNode {
Object element;
BinaryNode* left;
BinaryNode* right;
BinaryNode(const Object& theElement, BinaryNode* lt, BinaryNode* rt) :
element(theElement), left(lt), right(rt) {}
};
BinaryNode* root;
Comparator isLessThan;
BinaryNode* findMin(BinaryNode* t)const;
BinaryNode* findMax(BinaryNode* t)const;
bool contains(const Object& x, BinaryNode* t)const;
void printTree(BinaryNode* t)const;
void insert(const Object& x, BinaryNode*& t)const;
void remove(const Object& x, BinaryNode*& t)const;
void makeEmpty(BinaryNode*& t);
BinaryNode* clone(BinaryNode* t)const;
};
// constructor
template <class Object, class Comparator>
BinarySearchTree<Object, Comparator>::BinarySearchTree() {
root = NULL;
}
// copy constructor
template <class Object, class Comparator>
BinarySearchTree<Object, Comparator>::BinarySearchTree(const BinarySearchTree& rhs) {
root = rhs.clone(rhs.root);
}
// destructor
template <class Object, class Comparator>
BinarySearchTree<Object, Comparator>::~BinarySearchTree() {
makeEmpty();
}
/**
* Returns true if x is found in the tree
*/
template <class Object, class Comparator>
bool BinarySearchTree<Object, Comparator>::contains(const Object& x)const {
return contains(x, root);
}
/**
* Internal method to test if an item is in a subtree
* x is item to search for
* t is the node that roots the subtree
*/
template <class Object, class Comparator>
bool BinarySearchTree<Object, Comparator>::contains(const Object& x, BinaryNode* t)const {
if (t == NULL)
return false;
else if (isLessThan(x, t->element))
return contains(x, t->left);
else if (isLessThan(t->element, x))
return contains(x, t->right);
else
return true; // Match
}
/**
* Insert x into the tree; duplicates are ignored
*/
template <class Object, class Comparator>
void BinarySearchTree<Object, Comparator>::insert(const Object& x) {
insert(x, root);
}
/**
* Internal method to insert into a subtree
* x is the item to insert
* t is the node that roots the subtree
* Set the new root of the subtree
*/
template <class Object, class Comparator>
void BinarySearchTree<Object, Comparator>::insert(const Object& x, BinaryNode*& t)const {
//root = new BinaryNode(2, NULL, NULL);
if (t == NULL)
t = new BinaryNode(x, NULL, NULL);
else if (isLessThan(x, t->element))
insert(x, t->left);
else if (isLessThan(t->element, x))
insert(x, t->right);
else
return;
}
/**
* Return the smallest item
*/
template <class Object, class Comparator>
const Object& BinarySearchTree<Object, Comparator>::findMin()const {
BinaryNode* node = findMin(root);
if (NULL == node) throw out_of_range("BinarySearchTree is empty.");
else return node->element;
}
/**
* Internal method to find the smallest item in a subtree t.
* Return node containing the smallest item
*/
template <class Object, class Comparator>
typename BinarySearchTree<Object, Comparator>::BinaryNode*
BinarySearchTree<Object, Comparator>::findMin(BinaryNode* t)const {
if (t == NULL)
return NULL;
else if (t->left == NULL)
return t;
return findMin(t->left);
}
/**
* Return the largest item
*/
template <class Object, class Comparator>
const Object& BinarySearchTree<Object, Comparator>::findMax()const {
BinaryNode* node = findMax(root);
if (NULL == node) throw out_of_range("BinarySearchTree is empty.");
else return node->element;
}
/**
* Internal method to find the largest item in a subtree t.
* Return node containing the largest item
*/
template <class Object, class Comparator>
typename BinarySearchTree<Object, Comparator>::BinaryNode*
BinarySearchTree<Object, Comparator>::findMax(BinaryNode* t)const {
if (t == NULL)
return NULL;
else if (t->right == NULL)
return t;
return findMax(t->right);
}
/**
* Remove x from the tree
*/
template <class Object, class Comparator>
void BinarySearchTree<Object, Comparator>::remove(const Object& x) {
remove(x, root);
}
/**
* Internal method to remove from a subtree
* x is the item to remove
* t is the node that roots the subtree
* Set the new root of the subtree
*/
template <class Object, class Comparator>
void BinarySearchTree<Object, Comparator>::remove(const Object& x, BinaryNode*& t)const {
if (NULL == t)
return;
else if (isLessThan(x, t->element))
remove(x, t->left);
else if (isLessThan(t->element, x))
remove(x, t->right);
else if (NULL != t->left && NULL != t->right) { // there are both left son and right son
// 用结点t的右子树的最小结点来替代t
// 再递归调用从t的右子数中删除t->element这个结点
t->element = findMin(t->right)->element;
remove(t->element, t->right);
}
else {
BinaryNode* oldNode = t;
t = (t->left != NULL) ? t->left : t->right;
delete oldNode;
}
}
// makeEmpty
template <class Object, class Comparator>
void BinarySearchTree<Object, Comparator>::makeEmpty() {
makeEmpty(root);
}
/**
* Internal method to make subtree empty
*/
template <class Object, class Comparator>
void BinarySearchTree<Object, Comparator>::makeEmpty(BinaryNode*& t) {
if (t != NULL) {
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = NULL;
}
/**
* Deep Copy
*/
template <class Object, class Comparator>
const BinarySearchTree<Object, Comparator>&
BinarySearchTree<Object, Comparator>::operator=(const BinarySearchTree<Object, Comparator>& rhs) {
if (this != &rhs) {
this->makeEmpty();
this->root = rhs.clone(rhs.root);
}
return *this;
}
/**
* Internal method to clone subtree
*/
template <class Object, class Comparator>
typename BinarySearchTree<Object, Comparator>::BinaryNode*
BinarySearchTree<Object, Comparator>::clone(BinaryNode* t)const {
if (t == NULL) return NULL;
else return new BinaryNode(t->element, clone(t->left), clone(t->right));
}
/**
* Print the subtree
*/
template <class Object, class Comparator>
void BinarySearchTree<Object, Comparator>::printTree()const {
printTree(root);
}
/**
* Internal method to print the subtree
*/
template <class Object, class Comparator>
void BinarySearchTree<Object, Comparator>::printTree(BinaryNode* t)const {
if (t == NULL) return;
printTree(t->left);
printTree(t->right);
std::cout << t->element << " ";
}
#endif
#include "BinarySearchTree.h"
using namespace std;
void printTree(BinarySearchTree<int>& ibst, string s);
int main()
{
BinarySearchTree<int> ibst;
ibst.insert(6);
ibst.insert(2);
ibst.insert(1);
ibst.insert(8);
ibst.insert(7);
ibst.insert(100);
BinarySearchTree<int> ibst2(ibst);
printTree(ibst2, "ibst2");
ibst.remove(7);
ibst.remove(100);
BinarySearchTree<int> ibst3 = ibst;
printTree(ibst3, "ibst3");
ibst.insert(4);
ibst.insert(3);
printTree(ibst, "ibst");
if (ibst.contains(6)) cout << "ibst contains 6" << endl;
else cout << "ibst doesn't contain 6" << endl;
if (ibst.contains(10)) cout << "ibst contains 10" << endl;
else cout << "ibst doesn't contain 10" << endl;
if (!ibst.isEmpty()) cout << "ibst isn't empty" << endl;
else cout << "ibst is empty" << endl;
ibst.makeEmpty();
if (!ibst.isEmpty()) cout << "ibst isn't empty" << endl;
else cout << "ibst is empty" << endl;
system("pause");
return 0;
}
void printTree(BinarySearchTree<int>& ibst, string s) {
cout << s << ": ";
ibst.printTree();
cout << endl;
cout << s << ".max: " << ibst.findMax()
<< " " << s << ".min: " << ibst.findMin();
cout << endl << endl;
}