首页 > 代码库 > 二叉树删除详解

二叉树删除详解

二叉查找树的删除过程:

假设要删除树T中的某节点z,此时对于如何删除z要分三种情况考虑:

1.      z无子女:此时直接删除z即可

//z无子女
TREE-DELETE0(T,z)
{
	if(z == left[p[z]])
		left[p[z]] = NULL;
	else
		right[p[z]] = NULL;
	p[z] = NULL;
}

2.      z有一个子女:用其子节点代替自己即可

//z只有一个子女
TREE-DELETE1(T,z)
{
	//y为z的子女
	if(left[z] !=NULL)
		y = left[z];
	else
		y = right[z];
	//用y代替z并将z删除
	if(z == left[p[z]])
		p[y] = left[p[z]];
	else
		p[y] = right[p[z]];
	p[z] = NULL;
}

3.      z有两个子女:删除z的后继y(y不会有左子女,删除T中的y对应情况1或2),再用y的内容代替z的内容

//z有两个子女(这里实际上是删除了y)
TREE-DELETE2(T,z)
{
	y = TREE-SUCCESSOR(z);
	x = right[y];
	//z的后继y无子女
	if(x == NULL)
		TREE-DELETE0(T,y);
	else
		TREE-DELETE1(T,y);
	key[z] = key[y];
}

删除二叉查找树的总过程:

TREE-DELETE(T,z)
{
	if(z == root[T])
	{root[T] = NULL;return;}
	bool bleftEmpty = (left[z] == NULL);
	bool brightEmpty = (right[z] == NULL);
	//左右均不为空
	if(!bleftEmpty && !brightEmpty )
		TREE-DELETE2(T,z);
	//左右均为空
	else if(bleftEmpty && brightEmpty)
		TREE-DELETE0(T,z);
	//只有一个子女
	else 
		TREE-DELETE1(T,z);
}

可简写为:

1.确定y为要删除的节点:若z无子女则y为z;若z仅有一个子女则y为该子女;若z有两个子女则y为z的后继

if(left[z] == NULL || right[z] == NULL)
		y = z;
	else
		y = TREE-SUCCESSOR(z);
2.将x置为y的非空子女。若y无子女,则x置为空

if(left[y] != NULL)
		x = left[y];
	else
		x = right[y];
3.通过修改p[y]和x的指针删除y

	if(x != NULL)
		p[x] = p[y];
	if(p[y] == NULL)
		root[T] = x;
	else if(y == left[p[y]])
		left[p[y]] = x;
	else
		right[p[y]] = x;
4.如果z的后继就是要被删除的节点,则将y中的内容复制置z:

if(y != z)
		key[z] = key[y];
即:

TREE-DELETE(T,z)
{
	//确定y为要删除的节点
	if(left[z] == NULL || right[z] == NULL)
		y = z;
	else
		y = TREE-SUCCESSOR(z);
	if(left[y] != NULL)
		x = left[y];
	else
		x = right[y];
	if(x != NULL)
		p[x] = p[y];
	if(p[y] == NULL)
		root[T] = x;
	else if(y == left[p[y]])
		left[p[y]] = x;
	else
		right[p[y]] = x;
	if(y != z)
		key[z] = key[y];
}


二叉树删除详解