二叉搜索树的性质:对任何结点x,其左子树中的关键字最大不超过x.key,其右子树中的关键字最小不低于x.key。其数据元素集合包括每个节点,每个节点又包含节点的值和它的左儿子和右儿子。基本操作由:查找、最大关键字元素和最小关键字元素、插入、删除,这些基本操作耗费的时间均为θ(lgn)(与高度成正比)。遍历一棵有n个结点的二叉搜索树需要耗费θ(n)的时间,
#include <iostream>
using namespace std;
template <class T>
struct BinaryNode
{
T element;
BinaryNode *left;
BinaryNode *right;
BinaryNode(const T& theElement,BinaryNode *lt,BinaryNode *rt) :
element(theElement),left(lt),right(rt){ }
};
template <class T>
class BinarySearchTree
{
private:
BinaryNode<T> *m_root;
public:
BinarySearchTree();
BinarySearchTree(const BinarySearchTree& rhs);
~BinarySearchTree();
const T& findMin() const;
const T& findMax() const;
BinaryNode<T>* search(const T& x) const;
void printTreeInPrev() const;
void makeEmpty();
void insert(const T& x);
void remove(const T& x);
private:
//因为树的方法用到了很多递归, 所以这里我们需要申明如下的私有成员函数
void insert(const T& x, BinaryNode<T>* &t);
void remove(const T& x, BinaryNode<T>* &t);
BinaryNode<T>* findMin(BinaryNode<T>* t) const;
BinaryNode<T>* findMax(BinaryNode<T>* t) const;
BinaryNode<T>* search(const T& x, BinaryNode<T>* t) const;
void makeEmpty(BinaryNode<T>* &t);
void printTreeInPrev(BinaryNode<T>* t) const;
//void printTreeInMid(BinaryNode<T>* t)const;
//void printTreeInPost(BinaryNode<T>* t)const;
};
template <class T>
BinarySearchTree<T>::BinarySearchTree()
{
m_root = NULL;
}
template <class T>
BinarySearchTree<T>::BinarySearchTree(const BinarySearchTree& rhs)
{
m_root = rhs.m_root;
}
template <class T>
BinarySearchTree<T>:: ~BinarySearchTree()
{
makeEmpty();
}
// return true if the x is found in the tree
template <class T>
BinaryNode<T>* BinarySearchTree<T>::search(const T& x) const
{
return search(x, m_root);
}
template <class T>
BinaryNode<T>* BinarySearchTree<T>::search(const T& x, BinaryNode<T>* t) const
{
/*if (t==nullptr||x==t->element)
return t;
if (x < t->element)
return search(x, t->left);
else if (x > t->element)
return search(x, t->right);*/
while (t != nullptr&&x != t->element)
{
if (x < t->element)
t = t->left;
else
t = t->right;
}
return t;
}
// find the min value in the tree
template <class T>
const T& BinarySearchTree<T>::findMin() const
{
return findMin(m_root)->element;
}
template <class T>
BinaryNode<T>* BinarySearchTree<T>::findMin(BinaryNode<T>* t) const
{
//二叉树的一个特点就是左子叶的值比根节点小, 右子叶的比根节点的大
/*if (!t)
return NULL;
if (t->left == NULL)
return t;
else
return findMin(t->left);*/
if (!t)
return NULL;
while (t->left != nullptr)
t = t->left;
return t;
}
// find the max value in the tree
template <class T>
const T& BinarySearchTree<T>::findMax() const
{
return findMax(m_root)->element;
}
template <class T>
BinaryNode<T>* BinarySearchTree<T>::findMax(BinaryNode<T>* t) const
{
//二叉树的一个特点就是左子叶的值比根节点小, 右子叶的比根节点的大
if (t != NULL)
while (t->right != NULL)
t = t->right;
return t;
}
//insert an element into tree
template <class T>
void BinarySearchTree<T>::insert(const T& x)
{
insert(x, m_root);
}
template <class T>
void BinarySearchTree<T>::insert(const T& x, BinaryNode<T>* &t)
{
if (t == NULL)
t = new BinaryNode<T>(x, NULL, NULL);//注意这个指针参数是引用
else if (x < t->element)
insert(x, t->left);
else if (x > t->element)
insert(x, t->right);
else
;//do nothing
}
//remove a element int a tree
template <class T>
void BinarySearchTree<T>::remove(const T& x)
{
return remove(x, m_root);
}
template <class T>
void BinarySearchTree<T>::remove(const T& x, BinaryNode<T>* &t)
{
if (t == NULL)
return;
if (x < t->element)
remove(x, t->left);
else if (x > t->element)
remove(x, t->right);
else // now ==
{
if (t->left != NULL &&
t->right != NULL)//two child
{
t->element = findMin(t->right)->element;
remove(t->element, t->right);
}
else
{
BinaryNode<T> *oldNode = t;
t = (t->left != NULL) ? t->left : t->right;
delete oldNode;
}
}
}
template <class T>
void BinarySearchTree<T>::makeEmpty()
{
makeEmpty(m_root);
}
template <class T>
void BinarySearchTree<T>::makeEmpty(BinaryNode<T>* &t)
{
if (t)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = NULL;
}
//Print tree
template <class T>
void BinarySearchTree<T>::printTreeInPrev() const
{
printTreeInPrev(m_root);
}
template <class T>
void BinarySearchTree<T>::printTreeInPrev(BinaryNode<T>* t) const
{
if (t)
{
printTreeInPrev(t->left);
cout << t->element;
printTreeInPrev(t->right);
}
}