二叉排序树又称二叉查找树,它是一种对排序和查找都有用的特殊二叉树。
二叉排序树的定义:
二叉排序树或者是一颗空树,或者具有下列性质的二叉树:
(1)、若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值。
(2)、若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。
(3)、它的左、右子树也分别为二叉排序树。
二叉排序树是递归定义的。由定义可以得出二叉排序树的一个重要性质:中序遍历一颗二叉排序树时可以得到一个结点值递增的有序序列。
二叉排序树的二叉链表存储表示:
typedef struct
{
KeyType key; //关键字项
InfoType otherinfo; //其他数据项
}ElemType; //每个结点的数据域的类型
typedef struct BSTNode
{
ElemType data;
struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
二叉排序树的递归查找
算法步骤:
1、若二叉排序树为空,则查找失败,返回空指针。
2、若二叉排序树非空,将给定值key于根结点的关键字T->data.key进行比较:
2.1、若key等于T->data.key,则查找成功,返回根结点地址。
2.2、若key小于T->data.key,则递归查找左子树。
2.3、若key大于T->data.key,则递归查找右子树。
BSTree SearchBST(BSTree T,KeyType key)
{
if((!T)||key == T->data.key){
return T;
}else if(key < T->data.key){
return SearchBST(T->lchild,key);
}else{
return SearchBST(T->rchild,key);
}
}
二叉排序树的插入
二叉排序树的插入操作是以查找为基础的。要将一个关键字值为key的结点 *S插入到二叉排序树中,则需要从根结点向下查找,当树中不存在关键字等于key的结点时才进行插入。新插入的结点一定是一个新添加的叶子结点,并且查找不成功时查找查找路径上访问的最后一个结点的左孩子或右孩子结点。
算法步骤:
1、若二叉排序树为空,则待插入结点 *S作为根结点插入到空树中。
2、若二叉排序树非空,则将key于根结点的关键字T->data.key进行比较:
2.1、若key小于T->data.key,则将 *S插入左子树;
2.2、若key大于T->data.key,则将 *S插入右子树。
void InsertBST(BSTree &T,ElemType e)
{//当二叉排序树T中不存在关键字等于e.key的数据元素时,则插入该元素
if(!T)
{
S = new BSTNode;
S->data = e;
S->lchild = S->rchild = NULL;
T = S;
}else if(e.key < T->data.key){
ImsertBSt(T->lchild,e);
}else if(e.key > T->data.key){
InsertBST(T->rchild,key);
}
}
二叉排序树插入的基本过程是查找,所以时间复杂度同查找一样,是O(long2n)。
二叉排序树的创建
二叉排序树的创建是从空的二叉排序树开始的,每输入一个结点,经过查找操作,将新节点插入到当前二叉排序树的合适位置。
算法步骤:
1、将二叉排序树T初始化为空树。
2、读入一个关键字为key的结点。
3、如果读入的关键字key不是输入结束标志,则循环执行以下操作:
3.1、将此结点插入二叉排序树T中;
3.2、读入一个关键字为key的结点。
void CreatBST(BSTree &T)
{
T = NULL;
cin>>e;
while(e.key != ENDFLAG)//ENDFLAG为自定义常量,作为输入结束标志
{
InsertBST(T,e);
cin>>e;
}
}
假设有n个结点,则需要n此插入操作,而插入一个结点的算法时间度为O(log2n),所以创建二叉排序树算法的时间复杂度为O(nlog2n)。