二叉搜索树:
1、要么为一个空树
2、要么不是一个空树
2.1、如果有左子树,对于该树中的每一个节点来说,该节点的左子树上的所有节点都要比该节点小
2.2、如果有右子树,对于该树中的每一个节点来说,该节点的右子树上的所有节点都要比该节点大
下面我们采用递归方法以及非递归方法来实现一下对于二叉搜索树的插入、查找以及删除操作。
1、基本操作:这里的基本操作思路简单,且在之前的二叉树中详细讲述过,这里就不在过多的赘述,有需要者可以查看之前的文章:
二叉树的基本操作(递归实现前中后序遍历)
二叉树的基本操作(非递归实现前中后序遍历)
//初始化函数
void SearchTreeInit(SearchNode **root)
{
if(root == NULL)
{
//非法输入
return;
}
*root = NULL;
}
//销毁函数
void SearchTreeDestroy(SearchNode **root)
{
if(root == NULL)
{
//非法输入
return;
}
if(*root == NULL)
{
//空树
return;
}
//不是空树
//以后序遍历的顺序递归销毁
//1、递归销毁左子树
SearchTreeDestroy(&(*root)->lchild);
//2、递归销毁右子树
SearchTreeDestroy(&(*root)->rchild);
//3、销毁根节点
DestroyNode(*root);
*root = NULL;
}
2、插入操作
思路:1、如果我们当前要插入元素的树是一颗空树,那么我们直接将其插入即可。
2、如果不是空树,那么我们就要考虑元素插入以后的树海是不是一棵二叉搜索树。因此我们插入的方法就是:从根节点开始,与根节点的值相比较,如果比根节点的值小,那么就往根节点的左子树插入;如果比根节点的值大,就往根节点的右子树插入,如果相等,我们这里约定该二叉搜索树中不能有重复的元素所以一旦相等就直接插入失败返回。
//插入元素(递归版本)
void SearchTreeInsert(SearchNode **root,DataType to_insert)
{
if(root == NULL)
{
//非法输入
return;
}
if(*root == NULL)
{
//空树
//此时待插入的元素直接插到根节点的位置
SearchNode *new_node = CreateNode(to_insert);
*root = new_node;
return;
}
//不是空树
SearchNode *cur = *root;
if(to_insert < cur->data)
{
//待插入的元素比当前根结点的值小
//则递归的往左子树插入
SearchTreeInsert(&cur->lchild,to_insert);
}
else if(to_insert > cur->data)
{
//待插入的元素比当前根节点的值大
//则递归的往右子树插入
SearchTreeInsert(&cur->rchild,to_insert);
}
else
{
//待插入的元素和当前根节点的值相等
//我们约定该二叉搜索树中不能有重复的值
//则直接返回
return;
}
}
//测试一下
void TestInsert()
{
Test_Header;
SearchNode *root;
SearchTreeInit(&root);
SearchTreeInsert(&root,'c');
SearchTreeInsert(&root,'a');
SearchTreeInsert(&root,'d');
SearchTreeInsert(&root,'b');
SearchTreeInsert(&root,'e');
printf("先序遍历结果为:");
SearchTreePreOrder(root);
printf("\n");
printf("中序遍历结果为:");
SearchTreeInOrder(root);
printf("\n");
}
测试结果如下:
//插入(非递归版本)
void SearchTreeInsert1(SearchNode **root,DataType to_insert)
{
if(root == NULL)
{
//非法输入
return;
}
if(*root == NULL)
{
//空树
SearchNode *new_node = CreateNode(to_insert);
*root = new_node;
return;
}
//不是空树
//要放置的位置
SearchNode *cur = *root;
//新元素的父节点
SearchNode *pre = NULL;
//循环找到要插入的位置
while(1)
{
if(cur == NULL)
{
//找到了要插入的位置
//退出循环
break;
}
if(to_insert > cur->data)
{
//保存父节点的位置(即当前节点)
pre = cur;
//去当前节点的右子树找
cur = cur->rchild;
}
else if(to_insert < cur->data)
{
//保存父节点的位置(即当前节点)
pre = cur;
//取当前节点的左子树找
cur = cur