二叉查找树

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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值