二叉搜索树

二叉搜索树的主要操作有插入,搜索,删除。

在介绍操作之前,先引入节点

struct Node
{
	int key;
	Node *parent,*left,*right;
}; 

节点有4个属性,键值,父亲指针,左子节点指针,右子节点指针

以下逐一进行介绍

1.插入

void insert(int k)//传入键值k
{
	Node *y=NIL;
	Node *x=root;
	Node *z;
	z=(Node *)malloc(sizeof(Node));
	z->key=k;
	z->left=NIL;
	z->right=NIL;//以上均为初始化
	while(x!=NIL)
	{
		y=x;//y在循环结束后作为父节点使用
		if(z->key<x->key)
		x=x->left;
		if(z->key>x->key)
		x=x->right;
	}//搜索树左边键值小,右边大,中间在其中
	z->parent=y;
	if(y==NIL)
	root=z;//如果y仍为空,则说明二叉树当前为空,z为根节点
	else if(z->key<y->key)
	y->left=z;
	else
	y->right=z;
}

2.搜索

Node *find(Node *u,int k)//u从根节点开始搜索键值为k的节点
{
   while(u!=NIL&&k!=u->key)//根据值的大小决定往哪个方向走
   {
   	if(u->key<k) u=u->right;
   	else
   	u=u->left;
	} 
	return u;
} 

3.

删除操作是比较复杂的操作。

根据要删除的节点的子节点情况进行分类。

(1)

无根节点,这就很简单,直接删就完事儿了。

(2)

有一个根节点,这也并不复杂,

让其子节点指向其父节点,把节点删掉,也就结束了。

(3)

有两个节点的情况就稍稍复杂一点了。

取待删除节点中序遍历的后一个,因为中序遍历的序列是递增的,也就是右子树最小的那个数,然后将改变指针,让x连到y的父节点,待删除的节点z值变为y的值,梳理一下x,y,z的关系,z是本来应该要删除的节点,但要让z中序排列的后一个y来顶替z,所以删除节点y,让x与y的父节点相连。

Node *treeMinimum(Node *x)
{
	while(x->left!=NIL) x=x->left;
	return x;
}
Node *treeSuccessor(Node *x)//寻找中序排列的后一个
{
	if(x->right!=NIL) return treeMinimum(x->right);//有右子树的情况
	Node *y=x->parent;//往上走
	while(y!=NIL&&x==y->right)//这里不好理解的话可以自己画个图看看
	{
		x=y;
		y=y->parent;
	}
	return y;
}
void TreeDelete(Node *z)
{
	Node *y;
	Node *x;
	if(z->left==NIL||z->right==NIL) y=z;//无子节点直接删除
	else y=treeSuccessor(z);
	if(y->left!=NIL)
	x=y->left;//有左子节点一定选择左子节点
	else
	x=y->right;
	if(x!=NIL)//后面就是联系y的父亲节点和x
	x->parent=y->parent;
	if(y->parent==NIL)
	root=x;
	else if(y==y->parent->left)
	y->parent->left=x;
	else
	y->parent->right=x;
	if(y!=z)
	z->key=y->key;
	free(y);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值