二叉查找树 (Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的 二叉树 : 若它的左子树不空,则左子树上所有结点的值均小于它的 根结点 的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为 二叉排序树 。. 二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势;所以应用十分广泛,例如在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作。
二叉排序树的操作主要有:
1.查找:递归查找是否存在key。
2.插入:原树中不存在key,插入key返回true,否则返回false。
3.构造:循环的插入操作。
4.删除:
(1)叶子节点:直接删除,不影响原树。
(2)仅仅有左或右子树的节点:节点删除后,将它的左子树或右子树整个移动到删除节点的位置就可以,子承父业。
(3)既有左又有右子树的节点:找到须要删除的节点p的直接前驱或者直接后继s,用s来替换节点p,然后再删除节点s。
BinTree结构定义如下:
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
操作集如下:
- 函数Insert将X插入二叉搜索树BST并返回结果树的根结点指针;
- 函数Delete将X从二叉搜索树BST中删除,并返回结果树的根结点指针; 如果X不在树中,则打印一行Not Found并返回原树的根结点指针;
- 函数Find在二叉搜索树BST中找到X,返回该结点的指针;如果找不到则返回空指针;
- 函数FindMin返回二叉搜索树BST中最小元结点的指针;
- 函数FindMax返回二叉搜索树BST中最大元结点的指针。
BinTree Insert( BinTree BST, ElementType X )
{
if(!BST)
{
BST=(BinTree)malloc(sizeof(struct TNode));
BST->Data=X;
BST->Left=NULL;
BST->Right=NULL;
}
else
{
if(X<BST->Data) BST->Left=Insert(BST->Left,X);
else BST->Right=Insert(BST->Right,X);
}
return BST;
}
BinTree Delete( BinTree BST, ElementType X )
//层层递归,每次调用Delete返回调用Delete函数的结点的左/右结点
{
BinTree tem=NULL;
if(!BST) printf("Not Found\n");
else
{
if(X<BST->Data)
BST->Left=Delete(BST->Left,X);
else if(X>BST->Data)
BST->Right=Delete(BST->Right,X);
else //找到要删除节点
{
if(BST->Left&&BST->Right) //左右结点都存在
{
//在右子树中找最小的元素替换被删除结点(也可以找左子树中最大的元素)
tem=FindMin(BST->Right);
BST->Data=tem->Data;
BST->Right=Delete(BST->Right,tem->Data);
//删除右子树中的最小元素,此次调用中又有多层递归,层层递归后返回给当前BST一个已删除最小元素的右子树的根结点,使树又完整连接。
}
else
{
tem=BST;
if(BST->Left&&!BST->Right) BST=BST->Left;
else if(BST->Right&&!BST->Left) BST=BST->Right;
else BST=NULL;
free(tem);
}
}
}
return BST;
}
Position Find( BinTree BST, ElementType X )
{
if(!BST) return NULL;
BinTree T=BST;
if(T->Data==X) return T;
else if(X<T->Data) return Find(T->Left,X);
else return Find(T->Right,X);
}
Position FindMin( BinTree BST )
{
if(BST)
{
while(BST->Left)
BST=BST->Left;
}
return BST;
}
Position FindMax( BinTree BST )
{
if(BST)
{
while(BST->Right)
BST=BST->Right;
}
return BST;
}
// 先序遍历
void PreorderTraversal( BinTree BT ){
if(BT){
printf(" %d",BT->Data);
PreorderTraversal(BT->Left);
PreorderTraversal(BT->Right);
}
}
// 中序遍历
void InorderTraversal( BinTree BT ){
if(BT){
InorderTraversal(BT->Left);
printf(" %d",BT->Data);
InorderTraversal(BT->Right);
}
}