# 二叉搜索树的查找、插入、删除操作

（1）若左子树不空，则左子树上所有结点的值均小于它的根结点的值；
（2）若右子树不空，则右子树上所有结点的值均大于它的根结点的值；
（3）左、右子树也分别为二叉排序树；
（4）没有键值相等的结点

1. 考虑是否是空树、或者需要删除的结点不在树中。

2. 考虑整棵树只有一个结点，删除后需要修改入参，将整棵树置空。

3. 考虑删除的结点是叶子结点。

4. 待删除的结点只有左子树，或者只有右子树。

5.待删除的结点有左右子树。

//bsearchtree.h

#include <stdio.h>

typedef struct Item{
int m_item;
/**/
}Item;

typedef struct Node{
int key;
Item item;
}Node;

typedef struct Tree{
Node node;
struct Tree * lchild;
struct Tree * rchild;
}Tree;

typedef struct Tree * TreePointer;

const Tree * mybsearch(const Tree * tree, int key);
int binsert(TreePointer * ptree, const Node * nd);
int bdelete(TreePointer * ptree, int key);
void threeWayJoin(Tree * small, Tree * mid, Tree * big);
void twoWayJoin(Tree * small, Tree * big);
void split(Tree * tree, int k, Tree * small, Tree * mid, Tree * big);
void show(TreePointer tree);

//bsertchtree.c

#include "bsearchtree.h"
#include <stdlib.h>

const Tree * mybsearch(const Tree * tree, int key)
{
if(NULL == tree)
{
return NULL;
}
if(key == tree->node.key)
return tree;
if(key > tree->node.key)
return mybsearch(tree->rchild, key);
else
return mybsearch(tree->lchild, key);
}
/*循环实现
{
while(tree)
{
if(key == tree->node.key)
return tree;
if(key > tree->node.key)
{
tree = tree->rchild;
}
else
{
tree = tree->lchild;
}
}
return NULL;
}
*/
int binsert(TreePointer * ptree, const Node * nd)
{
Tree * current = *ptree;
Tree * prev = NULL;
Tree * pnew;

while(current)
{
if(nd->key == current->node.key)
{
return 0;
}
prev = current;
if(nd->key > current->node.key)
current = current->rchild;
else
current = current->lchild;
}

pnew = (Tree *)malloc(sizeof(Tree));
pnew->node = *nd;
pnew->lchild = pnew->rchild = NULL;

if(prev)
{
if(nd->key > prev->node.key)
prev->rchild = pnew;
else
prev->lchild = pnew;
}
else
*ptree = pnew;

return 1;
}

int bdelete(TreePointer * ptree, int key)
{
Tree * current = *ptree;
Tree * prev = NULL;
int flag = 0;//找到关键字为1， 没找到为0

/*查找树中是否存在关键字项key, current 指向含key的结点， prev指向其前驱结点*/
while(current)
{
if(key == current->node.key)
{
flag = 1;
break;
}
prev = current;
if(key > current->node.key)
current = current->rchild;
else
current = current->lchild;
}
//没有查找到需要删除的结点
if(!flag)
{
return 0;
}
//整棵树只有一个结点
if((*ptree)->lchild == NULL && (*ptree)->rchild == NULL)
{
free(*ptree);
*ptree = NULL;
return 1;
}
//待删除的结点是叶子结点
if(current->lchild == NULL && current->rchild == NULL)
{
if(prev->lchild == current)
prev->lchild = NULL;
else
prev->rchild = NULL;
}
//待删除的结点只有一个右子结点
else if(current->lchild == NULL)
{
if(prev->lchild == current)//前驱结点的左指针指向当前结点
prev->lchild = current->rchild;
else //前驱结点的右指针指向当前结点
prev->rchild = current->rchild;
}
//待删除的结点只有一个左子结点
else if(current->rchild == NULL)
{
if(prev->lchild == current)
prev->lchild = current->lchild;
else
prev->rchild = current->lchild;
}
//待删除的结点有2个子结点
else
{
//寻找左子树中key最大的结点， save保存其前驱结点
Tree * save = current;
Tree * temp = current->lchild;

while(temp->rchild)
{
save = temp;
temp = temp->rchild;
}
if(save == current)
save->lchild = temp->lchild;
else
save->rchild = temp->lchild;
current->node = temp->node;
current = temp;
}
free(current);
return 1;
}

void threeWayJoin(Tree * small, Tree * mid, Tree * big);
void twoWayJoin(Tree * small, Tree * big);
void split(Tree * tree, int k, Tree * small, Tree * mid, Tree * big);
void show(TreePointer tree)
{
if(tree)
{
printf("key = %d, data = %d\n", tree->node.key, tree->node.item.m_item);
show(tree->lchild);
show(tree->rchild);
}
}

//test.c  ,测试的数据可以自己修改

#include "bsearchtree.h"
#include <stdlib.h>
#include <time.h>

int main(void)
{
int i;
Node node;
TreePointer tree;

srand(time(NULL));
tree = NULL;

/*
for(i =0; i < 10; i++)
{
node.key = rand() % 10;
node.item.m_item = i;
binsert(&tree, &node);
printf("insert: key = %d, data = %d\n", node.key, node.item.m_item);
}
*/
node.key = 1;
node.item.m_item = 0;
binsert(&tree, &node);

node.key = 8;
binsert(&tree, &node);

node.key = 3;
binsert(&tree, &node);

node.key = 2;
binsert(&tree, &node);

node.key = 9;
binsert(&tree, &node);

printf("after insert: \n");
show(tree);
printf("after delete: \n");
bdelete(&tree, 8);
show(tree);

return 0;
}

• 本文已收录于以下专栏：

## 二叉查找树（二叉排序树）创建，插入，删除操作。

• chenfs1992
• 2014年07月31日 22:29
• 1179

## 二叉排序树（查询、插入、删除）

“二叉排序树，又称为二叉查找树。它或者是一颗空树，或者具有下列性质的二叉树。 若它的左子树不空，则左子树上所有节点的值均小于它的根节点的值； 若它的右子树不空，则右子树上所有节点的值均...
• wangyunyun00
• 2014年04月14日 22:00
• 17348

## 二叉搜索树的定义、查找、插入和删除

• yanxiaolx
• 2016年07月21日 21:59
• 5164

## 二叉搜索树的插入，删除

• li_zhenxing
• 2014年06月01日 21:59
• 1006

## 二叉排序树的建立、插入、删除、查找、4种遍历 C++完整实现

#include #include #include using namespace std; typedef int KeyType; #define NUM 13 class BinSTree;...
• u010367506
• 2014年04月01日 15:25
• 2847

## 二叉查找树(1) - 查找以及插入

• shltsh
• 2015年06月15日 23:03
• 1352

## 【算法导论】二叉搜索树的插入和删除

• cyp331203
• 2015年01月11日 11:47
• 1655

## 二叉搜索树(Binary Search Tree)的递归和非递归代码实现(C++)

• dawning7670
• 2016年03月11日 22:59
• 726

## 二叉排序树的操作（建立、插入、删除和查找）

• yushanjin0767
• 2013年08月22日 15:55
• 1551

## 二叉排序树的查找、插入、删除、建立

• u011028179
• 2014年08月16日 10:45
• 485

举报原因： 您举报文章：二叉搜索树的查找、插入、删除操作 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)