二叉搜索树的主要操作有插入,搜索,删除。
在介绍操作之前,先引入节点
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);
}