(1) 左子树不空,则左子树上的所有结点的值均小于根结点的值
(2) 右子树不空,则右子树上的所有结点的值均大于根结点的值
二叉查找树可以为空,二叉查找树是递归定义的,也就是说其左右子树也为二叉查找树。
二叉查找树是一种动态查找表,可以进行动态地插入和删除。前面的定义中我们假定二叉查找树不含有相同元素。
由定义可知二叉查找树的中序序列为一个递增序列
常见的二叉查找树操作有求最小元素findMin(),求最大元素findMax(),判断查找树是否非空isEmpty(),判断是否包含给定元素contains(),输出所有元素printTree(),置空查找树makeEmpty(),向查找树中插入给定元素x,insert(x),在查找树中删除给定元素x,remove(x)。
下面先讨论最重要的插入和删除操作,接着给出完整的C风格实现。
1、基本结构定义
class Student
{
public:
int key;
string major;
Student(int k=int(),string s="") : key(k), major(s){}
void operator=(const Student& rhs);
};
typedef Student ElementType;
typedef int KeyType;
typedef struct BSTNode
{
ElementType data;
struct BSTNode* lchild;
struct BSTNode* rchild;
}BSTNode, *BST;
详细信息请看后面完整程序
2、插入
(1) 不允许插入相同关键字,若二叉查找树中存在该关键字,则不插入
(2) 我们可以先检索二叉树,看查找树中是否含有该关键字,若不存在,再做一次扫描将结点插入到适当位置。使用这种方式,为插入一个该关键字,做了两次扫描。
(3) 注意到,插入的结点总是作为某一叶子节点的子结点,我们可以在第一次扫描过程中就确定待插入的位置,即把查找是否存在该关键字和查找可能的插入点在一次扫描中完成,提高插入效率。
(4) 查找递归实现
/*
description:在以t为根结点的二叉查找树中,查找关键字为key的结点
若查找成功,指针p指向该结点,返回true,
否则指向查找路径上的最后一个结点并返回false
指针f指向根结点t的父节点
*/
bool searchBST_recursion(BST t, KeyType key, BSTNode* f, BSTNode*& p)
{
if(t == NULL)//查找失败
{
p = f;
return false;
}
else if(key == t->data.key)//查找成功
{
p = t;
return true;
}
else if(key < t->data.key)
return searchBST_recursion(t->lchild,key,t,p);//左子树中继续查找
else
return searchBST_recursion(t->rchild,key,t,p);//右子树中继续查找
}
(5) 查找非递归实现
bool searchBST(BST t, KeyType key, BSTNode* f, BSTNode* &p)
{
while(t && key != t->data.key)
{
f = t;
if(key < t->data.key)
{
t = t->lchild;
}
else
{
t = t->rchild;
}
}
if(t)//查找成功
{
p = t;
return true;
}
else
{
p = f;
return false;
}
}
(6) 插入给定元素
void insertBST(BST& t,ElementType elem)
{
BSTNode * p = NULL;
if(!searchBST(t, elem.key, NULL, p))//查找失败,不含该关键字&#