二叉搜素树,又名二叉查找树,二叉排序树。
它具有以下特点:
1、若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2、若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3、它的左、右子树也分别为二叉排序树。
下面我们实现以下二叉搜索树的一些基本操作:
1、初始化
2、销毁
3、插入
4、删除
5、查找
首先我们要先构建一个搜索二叉树的结构体,里面含有一个元素,两个结构体指针,一个指向左子树,一个指向右子树。
typedef struct SearchTreeNode{
SearchTreeType data;
struct SearchTreeNode* lchild;
struct SearchTreeNode* rchild;
}SearchTreeNode;
1、初始化
初始化的操作就是把二叉搜索树置为空树。
void SearchTreeInit(SearchTreeNode** root)
{
if(root == NULL)
{
return;
}
*root = NULL;
return;
}
2、销毁
将根结点free掉,再将根结点指向空。
void SearchTreeDestory(SearchTreeNode** root)
{
if(root == NULL)
{
return;
}
free(*root);
*root = NULL;
}
3、插入
当二叉树为空时,创建一个节点,将根结点指向新节点。
当二叉树不为空时,定义一个ret节点,根结点指向ret节点。将我们插入的元素与ret->data进行比较,如果大于ret->data,那么就递归访问它的右子树,如果小于ret->data,那么就递归的访问它的左子树。直到找到要插入的合适位置进行插入。
void SearchTreeInsert(SearchTreeNode** root,SearchTreeType to_insert)
{
if(root == NULL)
{
return;
}
if(*root == NULL)
{
SearchTreeNode* newnode = SeaechTreeCreate(to_insert);
*root = newnode;
}
SearchTreeNode* ret = *root;
if(to_insert > ret->data)
{
SearchTreeInsert(&ret->rchild,to_insert);
}
else if(to_insert < ret->data)
{
SearchTreeInsert(&ret->lchild,to_insert);
}
else
{
return;
}
}
4、删除
按给定的元素值进行删除,首先我们要先找到这个元素,定义一个节点cur,让根结点指向cur。然后一直递归的进行比较,直到找到要删除的元素值。
要删除的元素的位置还要分为四种情况:
1、左子树,右子树都为空
此情况下将元素的父节点直接指向NULL,再free掉这个元素就可以了。
2、左子树不为空,右子树为空
此情况下将元素的父节点指向元素的左子树,free掉元素。
3、左子树为空,右子树不为空
此情况下将元素的父节点指向元素的右子树,free掉元素。
4、左子树不为空,右子树也不为空
此情况下,我们要将删除的这个元素与它的右子树中最小的值进行交换后删除。
void SearchTreeMove(SearchTreeNode** root,SearchTreeType to_delete)
{
if(root == NULL)
{
return;
}
if(*root == NULL)
{
return;
}
SearchTreeNode* cur = *root;
if(to_delete > cur->data)
{
return SearchTreeMove(&cur->rchild,to_delete);
}
if(to_delete < cur->data)
{
return SearchTreeMove(&cur->lchild,to_delete);
}
else
{
if(cur->lchild == NULL && cur->rchild == NULL)
{
*root = NULL;
free(cur);
cur = NULL;
return;
}
else if(cur->lchild != NULL && cur->rchild == NULL)
{
*root = cur->lchild;
free(cur);
cur = NULL;
return;
}
else if(cur->lchild == NULL && cur->rchild != NULL)
{
*root = cur->rchild;
free(cur);
cur = NULL;
return;
}
else
{
SearchTreeNode* min = cur->rchild;
while(cur->lchild != NULL)
{
min = min->lchild;
}
cur->data = min->data;
SearchTreeMove(&cur->rchild,min->data);
free(min);
min = NULL;
return;
}
}
}
5、查找
查找就是递归的进行比较要查找的元素值和二叉树的所有元素值,直到找到,再返回这个值。
SearchTreeNode* SearchTreeFind(SearchTreeNode* root,SearchTreeType to_find)
{
if(root == NULL)
{
return NULL;
}
if(to_find > root->data)
{
SearchTreeFind(root->rchild,to_find);
}
else if(to_find < root->data)
{
SearchTreeFind(root->lchild,to_find);
}
else
{
return root;
}
}