1.新建结点操作
node* new_node(int v)//新建一个权值为v的结点
{
node *new_node=new node;
new_node->data=v;
new_node->lchild=new_node->rchild=0;
return new_node;
}
2.查找操作
void search(node *root,int x)
{
if(root=NULL) return;
if(root->data==x)
{
printf("%d\n",root->data);
return;
}
if(x>root->data) serach(root->rchild,x);
else search(root->lchild,x);
}
3.插入操作
void insert(node* &root,int v)
{
if(root==NULL)//没找到,说明要插入
{
root=new_node(v);
return;
}
if(v==root->data) return;//如果有,则不插入
if(v>root->data) insert(root->rchild,v);
else insert(root->rchild,v);
}
4.建树操作
node* create(int a[],int n)//建树
{
node *node=NULL;
for(int i=0;i<n;i++)
{
insert(root,a[i]);
}
return root;
}
5.删除操作
因为要求删除一个结点以后仍然保持树为二叉排序树的结构,于是有两种处理方式,第一个是取被删除结点(设为root)的左子树的最大结点(称为前驱)代替root的位置,第二个是取root的右子树的最小结点(称为后继)代替root的位置。由子树也是二叉排序树的特性可知,左子树的最大结点即左子树的最右结点(对左子树递归查询rchild直至rchild=NULL才返回),右子树的最小结点即右子树的最左结点(对右子树递归查询lchild直至lchild=NULL才返回),注意不仅需要用前驱or后继取代root的值,还需要删除原本的前驱和后继(相当于拆东墙补西墙)。
node* find_min(node *root)//以root为根结点查找子树中最小的结点,查找root的后继应该使用find_min(root->rchild);
{
while(root->lchild!=NULL)
{
root=root->lchild;
}
return root;
}
node* find_max(node *root)//以root为根结点查找子树中最大的结点,查找root的前驱应该使用find_max(root->lchild);
{
while(root->rchild!=NULL)
{
root=root->rchild;
}
return root;
}
void tree_delete(node* &root,int v)
{
if(root->data==v)
{
if(root->lchild==NULL&&root->rchild==NULL)
{
root=NULL;
return;
}
if(root->lchild!=NULL)
{
node *pre=find_max(root->lchild);
root->data=pre->data;
tree_delete(root->lchild,pre->data);//从左子树中删除值为pre->data的结点(因为已经被用来代替root)
}
else if(root->rchild!=NULL)
{
node *pre=find_min(root->rchild);
root->data=pre->data;
tree_delete(root->rchild,pre->data);//从右子树中删除值为pre->data的结点(因为已经被用来代替root)
}
}
else if(v>root->data) tree_delete(root->rchild,v);
else if(v<root->data) tree_delete(root->lchild,v);
}