二叉搜索树也可称为二叉排序树,其树的特点是每一个节点的左孩子的值小于该节点的值,而右孩子则大于它。
为了便于实例化每个操作,用以下例子来说明问题。题目链接
1.先来看插入操作,对于每输进来的一个值在该二叉搜索树上去寻找符合上述规则的位置。比较每一个节点,比它大,则下一步走向左孩子,反之走向右孩子。
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);
}
//之所以BST->Left=Insert()而非BST=Insert()是因为最终返回的是整棵树的根节点,需要记录并返回上一节点。
return BST;
}
2.查找一个元素e是否在该二叉搜索树中。
根据相应规则小于走左边,大于走右边,直到找到或到叶节点也没有找到为止。
Position Find( BinTree BST, ElementType X )//BST中查找元素X
{
while(BST)
{
if(X<BST->Data)
BST=BST->Left;
else if(X>BST->Data)
BST=BST->Right;
else
return BST;
}
return BST;
}
3.查找该树中最小的元素,只要树不为空,则最小值必定在左下角,所以一直往左遍历即可。
Position FindMin( BinTree BST )
{
if(BST) //判断是否为空树的情况
{
while(BST->Left)
BST=BST->Left;
}
return BST;
}
4.查找最大值。与最小值相对应,最大值在搜索树的右下角。
Position FindMax( BinTree BST )
{
if(BST)
{
while(BST->Right)
BST=BST->Right;
}
return BST;
}
5.删除操作可分为四种情况。
1) 被删除的是叶子节点,则直接给上一层返回空即可。
2) 该节点只有左孩子,则将左孩子链接到被删除节点的父节点即可。
3) 该节点只有右孩子,则将右孩子链接到被删除节点的父节点即可。
4)被删节点左右孩子都存在,如果直接删除则树可能会断掉,可以通过转换删除来实现,有两种策略 1.找到该节点左子树的最大值来代替它,再删除最大值,因为左子树的最大值节点肯定没有右子树,则删除就变成 上述 2)的情况。2.找到该节点右子树的最小值来代替它,并删除最小值情况就成为上述3).....理解不了可以画图看看。
BinTree Delete( BinTree BST, ElementType X )
{
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)
{
BinTree temp=FindMax(BST->Left);//此处找的是左子树的最大值
BST->Data=temp->Data;
BST->Left=Delete(BST->Left,BST->Data);
}
else
{
if(!BST->Lef t&& BST->Right)
return BST->Right;
else if(!BST->Right && BST->Left)
return BST->Left;
else
return NULL;
}
}
return BST;
}
********************************************************************最后顺便附带上二叉搜索树的创建
typedef struct Btree *tree;
struct Btree{
tree left;
tree right;
bool flag;
ElementType data;
};
tree make_node(tree T,int n)//判断节点插入的位置,并返回当前树的根节点
{
if(!T)
{
T=(tree)malloc(sizeof(struct Btree));
T->data=n;
T->flag=false;
T->left=NULL;
T->right=NULL;
}
else
{
if(n<T->data)
T->left=make_node(T->left,n);
else
T->right=make_node(T->right,n);
}
return T;
}
tree creat_tree(int n)//创建一颗N的节点的树,并返回。
{
int e;
tree T=NULL,temp;
for(int i=0;i<n;i++)
{
scanf("%d",&e);
T=make_node(T,e);
}
return T;
}