二叉排序树删除结点的方法

go_Michael 2009-12-21 10:29:15

//数据结构与算法分析
void remove(const Type& x,BinaryNode*& p)
{
if(t == NULL)
return;
if(x < t->element)
remove(x,t->left);
else if(x > t->element)
remove(x,t->right);
else if(t->left != NULL && t->right !=NULL)
{
t->element=findMin(t->right)->element;
remove(t->element,t->right);
}
else
{
BinaryNode* oldNode = t;
t=(t->left != NULL) ? t->left : t->right;
delete oldNode;
}
}
BinaryNode* findMin(BinaryNode* t)
{
if(t!=NULL)
while(t->left!=NULL)
t=t->left;
return t;
}

//以下是课本上的
void remove(BinaryNode* t)
{
if(!p->rchild)
{
q=p;
p=p->lchird;
free(q);
}
else if(!p->lchild))
{
q=p;
p=p->right;
free(q);
}
else //左右子树均不空
{
q=p;
s=p->lchild;
while(s->right) //转左,然后向右到尽头
{
q=s;
s=s->rchild; //s指向被删除结点的前驱;
}
p->element=s->element;
if(q!=p) //重接*q右子树
q->rchild=s->lchild;
else //重接*q左子树
q->lchild=s->lchild;
delete s;
}
}

如下二叉排序树所示
6

2 8

1 5

3

4
如果要删除结点2的话 两种算法得到的结果不一样
第一种:
6

3 8

1 5

4

课本上的做了之后这样:
6

1 8

5

3

4

大家看看有什么问题
...全文
311 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
evidence 2009-12-21
  • 打赏
  • 举报
回复
对于一个二叉排序树,删除节点之后的树的结构是不只一种的,只要保证仍为二叉排序树就可以了,
你的做法也能保证它是一个二叉排序树,所以也是可以的
不一定要跟书上的结果一样的说
我还可以把它在处理一下成为二叉平衡的排序树,那跟上面两种都不同,但是它仍然是二叉排序树,就OK
go_Michael 2009-12-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 evidence 的回复:]
你的做法是找出被删结点(有左右子树的)右子树的最小结点,代替当前被删结点,在删除右子树中的最小结点
书上的做法是被删结点有左右子树的,则左子树的最大结点代替当前被删结点,在删除左子树中的最大结点,
个人认为没什么区别,都可行
不过你最后的递归调用删除右子树中的最小结点的做法效率并不好吧,可以借鉴书上的
[/Quote]

但是我按书上的做法和第一种做法结果不一样啊 模仿了张图你看到了
evidence 2009-12-21
  • 打赏
  • 举报
回复
你的做法是找出被删结点(有左右子树的)右子树的最小结点,代替当前被删结点,在删除右子树中的最小结点
书上的做法是被删结点有左右子树的,则左子树的最大结点代替当前被删结点,在删除左子树中的最大结点,
个人认为没什么区别,都可行
不过你最后的递归调用删除右子树中的最小结点的做法效率并不好吧,可以借鉴书上的
evidence 2009-12-21
  • 打赏
  • 举报
回复
我已经没话说了,这个你自己好好想想吧,
本来就没有多少问题的答案唯一
又不是算术题
go_Michael 2009-12-21
  • 打赏
  • 举报
回复
还是觉得有点想不通
二叉排序树的二叉链表存储结构的类型定义如下: typedef struct node{ int data; //用整数表示一个结点的名 struct node *LChild,*RChild; //左右指针域 }BSTNode,*BSTree; 设计算法并编写程序求解以下几个问题。 8 12 14 10 7 3 15 6 2 4 1 5 11 9 13 16 13 (1)键盘输入一个元素序列创建一棵二叉排序树,输出该二叉排序树的中序遍历序列; 例如,若输入 45,24,55,12,37,53,60,23,40,70 则创建的二叉排序树为: 输出结果为:12 23 24 37 40 45 53 55 60 70 (2)在(1)中所得的二叉排序树中插入一个值为 58 的结点,再输出它的中序遍历序列,输出 结果为:12 23 24 37 40 45 53 55 58 60 70 (3)在(1)中所得的二叉排序树删除值为 45 的结点,再输出它的中序遍历序列,输出结果 为:12 23 24 37 40 53 55 58 60 70 (4)利用(1)中所得的二叉排序树的所有叶子结点构造一个带头结点的单链表 L。要求不能 破坏这棵二叉排序树。所得的单链表 L 如下。 输出该链表各结点的值,输出结果为:23 40 53 70 (5)设计算法将(1)中所得的二叉排序树的左右子树进行交换,由于二叉树是一种递归定义, 所以子树的左右两棵子树也要相交换,依此类推。最后输出所得到的二叉树的中序遍历序列。 例如,经过上述操作后,(1)中所得的二叉排序树变为如下形式。 输出该二叉树的中序序列,结果为:70 60 55 53 45 40 37 24 23 12 (6)设计算法统计并输出(1)中所得的二叉排序树中只有一个孩子结点结点个数。输出结 果为:3(7)在(1)中所得的二叉排序树中,设计算法并编写程序输出结点 40 的所有祖先结点。输 出结果为:45 24 37

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧