二叉树的一个重要的应用是它们在查找中的使用。
二叉搜索树的概念相当容易理解,即:对于树中的每个结点X,它的左子树中所有关键字的值都小于X的关键字值,而它的右子树中的所有关键字值都大于X的关键字值。这意味着该树所有的元素都可以用某种统一的方式排序,如中序遍历,将获得元素的按升序排序。
/*bstree.h (btree.h is the header file for class BTree)*/
#ifndef __BINARY_SEARCH_TREE_H__
#define __BINARY_SEARCH_TREE_H__
#include "btree.h"
template<typename T>
class BSTree : public BTree<T>
{//不需要自行定义构造函数和copying函数,编译器合成的版本工作良好:它们会调用基类和各个数据成员的相应的构造函数和copying函数
public://public interfaces for core operations
BTNode<T>* Find(const T &data) const;
BTNode<T>* FindMin() const;
BTNode<T>* FindMax() const;
virtual BTNode<T>* Insert(const T &data);
virtual BTNode<T>* Delete(const T &data);
private://real functions implementing core operations
BTNode<T>* Find(const T &data, BTNode<T> *p) const;
BTNode<T>* FindMin(BTNode<T> *p) const;
BTNode<T>* FindMax(BTNode<T> *p) const;
virtual BTNode<T>* Insert(const T &data, BTNode<T> *p);//insert data in the proper place which is always a child of a leafnode.
virtual BTNode<T>* Delete(const T &data, BTNode<T> *p);
};
/*--------------------------------------------------------------------------------------------
*public interfaces for core operations
----------------------------------------------------------------------------------------------*/
template<typename T>
inline BTNode<T>* BSTree<T>::Find(const T &data) const
{
return Find(data, m_pNodeRoot);
}
template<typename T>
inline BTNode<T>* BSTree<T>::FindMin() const
{
return FindMin(m_pNodeRoot);
}
template<typename T>
inline BTNode<T>* BSTree<T>::FindMax() const
{
return FindMax(m_pNodeRoot);
}
template<typename T>
inline BTNode<T>* BSTree<T>::Insert(const T &data)
{
return Insert(data, m_pNodeRoot);
}
template<typename T>
inline BTNode<T>* BSTree<T>::Delete(const T &data)
{
return Delete(data, m_pNodeRoot);
}
/*-------------------------------------------------------------------------------------------------
*real functions implementing core operations
--------------------------------------------------------------------------------------------------*/
template<typename T>
inline BTNode<T>* BSTree<T>::Find(const T &data, BTNode<T> *p) const
{
if (NULL == p)
return NULL;
if (data < p->data)
return Find(data, p->left);
else if (data > p->data)
return Find(data, p->right);
else
return p;
}
template<typename T>
inline BTNode<T>* BSTree<T>::FindMin(BTNode<T> *p) const
{
if (NULL == p)
return NULL;
else if (NULL == p->left)
return p;
else
return FindMin(p->left);
}
template<typename T>
inline BTNode<T>* BSTree<T>::FindMax(BTNode<T> *p) const
{
if (NULL == p)
return NULL;
else if (NULL == p->right)
return p;
else
return FindMax(p->right);
}
//返回值:如果p为NULL,则返回值为新分配内存的指针;如果p不是NULL,则返回值即为p.
template<typename T>
inline BTNode<T>* BSTree<T>::Insert(const T &data, BTNode<T> *p)
{
if (NULL == p)//终止条件。只能插在页节点的子节点位置上。
{
try
{
p = new BTNode<T>;
}
catch (std::bad_alloc&)
{
return NULL;
}
p->data = data;
p->left = NULL;
p->right = NULL;
if (NULL == m_pNodeRoot)
{
m_pNodeRoot = p;
m_pNodeRoot->parent = NULL;
}
}
else if (data < p->data)
{
p->left = Insert(data, p->left);
if (p->left)
p->left->parent = p;
}
else if (data > p->data)
{
p->right = Insert(data, p->right);
if (p->right)
p->right->parent = p;
}
// else data is in the tree already, we'll do nothing!
return p;
}
//返回值:如果节点p的数据与data不等,则返回值即为p;如果相等,但有两个子节点,返回值也为p,有一个子节点,返回值为该子节点指针,
//如果无节点,返回值NULL。
template<typename T>
inline BTNode<T>* BSTree<T>::Delete(const T &data, BTNode<T> *p)
{
if (NULL == p)
{
// Error! data not found!
}
else if (data < p->data)
{
p->left = Delete(data, p->left);
}
else if (data > p->data)
{
p->right = Delete(data, p->right);
}
else if (p->left && p->right) // found it, and it has two children
{
BTNode<T> *pTmp = FindMin(p->right);
p->data = pTmp->data;
p->right = Delete(p->data, p->right);
}
else // found it, and it has one or zero children
{
BTNode<T> *pTmp = p;
if (NULL == p->left)
p = p->right;
else if (NULL == p->right)
p = p->left;
if (p)
p->parent = pTmp->parent;
if (m_pNodeRoot == pTmp)
m_pNodeRoot = p;
delete pTmp;
}
return p;
}
#endif // __BINARY_SEARCH_TREE_H
注意:上述实现有几个虚函数,这是因为二叉搜索树也常作为其他种类树的基类,而一般要重写插入和删除操作。