二叉树的删除
来源:互联网 发布:pdf.js获取pdf高度 编辑:程序博客网 时间:2024/05/22 01:16
二叉排序树的删除:
对于一般的二叉树来说,删去树中的一个结点是没有意义的,因为它将使以被删除的结点为根的子树变成森林,破坏了整棵树的结构
但是,对于二叉排序树,删去树上的一个结点相当于删去有序序列中的一个记录,只要在删除某个结点后不改变二叉排序树的特性即可。
但是上面这种方法,把r移来移去,很容易出错,其实在这里我们删除的只是p的元素值,而不是它的地址,所以完全没有必要移动指针。仔细观察,发现我们删除的地址实际上是p的左子树的最右边的叶子结点r的地址,所以我们只要把r的数据填到p中,然后把r删除即可。
对于一般的二叉树来说,删去树中的一个结点是没有意义的,因为它将使以被删除的结点为根的子树变成森林,破坏了整棵树的结构
但是,对于二叉排序树,删去树上的一个结点相当于删去有序序列中的一个记录,只要在删除某个结点后不改变二叉排序树的特性即可。
在二叉排序树上删除一个结点的算法如下:
btree * DeleteBST(btree *b, ElemType x) { if (b) { if (b->data == x) b = DelNode(b); else if (b->data > x) b->lchild = DeleteBST(b->lchild, x); else b->rchild = DeleteBST(b->rchild, x); } return b; }
其中删除过程有两种方法。
第一种过程如下:
1。若p有左子树,找到其左子树的最右边的叶子结点r,用该叶子结点r来替代p,把r的左孩子
作为r的父亲的右孩子。
2。若p没有左子树,直接用p的右孩子取代它。
第二种过程如下:
1。若p有左子树,用p的左孩子取代它;找到其左子树的最右边的叶子结点r,把p的右子树作为r
的右子树。
2。若p没有左子树,直接用p的右孩子取代它。
两种方法各有优劣,第一种操作简单一点点,但均衡性不如第二种,因为它将结点p的右子树
全部移到左边来了。下面将分别以两种种思路编写代码。
第一种:
btree * DelNode(btree *p) { if (p->lchild) { btree *r = p->lchild; //r指向其左子树; while(r->rchild != NULL)//搜索左子树的最右边的叶子结点r { r = r->rchild; } r->rchild = p->rchild; btree *q = p->lchild; //q指向其左子树; free(p); return q; } else { btree *q = p->rchild; //q指向其右子树; free(p); return q; } }
第二种:
btree * DelNode(btree *p) { if (p->lchild) { btree *r = p->lchild; //r指向其左子树; btree *prer = p->lchild; //prer指向其左子树; while(r->rchild != NULL)//搜索左子树的最右边的叶子结点r { prer = r; r = r->rchild; } if(prer != r)//若r不是p的左孩子,把r的左孩子作为r的父亲的右孩子 { prer->rchild = r->lchild; r->lchild = p->lchild; //被删结点p的左子树作为r的左子树 } r->rchild = p->rchild; //被删结点p的右子树作为r的右子树 free(p); return r; } else { btree *q = p->rchild; //q指向其右子树; free(p); return q; } }
但是上面这种方法,把r移来移去,很容易出错,其实在这里我们删除的只是p的元素值,而不是它的地址,所以完全没有必要移动指针。仔细观察,发现我们删除的地址实际上是p的左子树的最右边的叶子结点r的地址,所以我们只要把r的数据填到p中,然后把r删除即可。
//算法如下: btree * DelNode(btree *p) { if (p->lchild) { btree *r = p->lchild; //r指向其左子树; btree *prer = p->lchild; //prer指向其左子树; while(r->rchild != NULL)//搜索左子树的最右边的叶子结点r { prer = r; r = r->rchild; } p->data = r->data; if(prer != r)//若r不是p的左孩子,把r的左孩子作为r的父亲的右孩子 prer->rchild = r->lchild; else p->lchild = r->lchild; //否则结点p的左子树指向r的左子树 free(r); return p; } else { btree *q = p->rchild; //q指向其右子树; free(p); return q; } }
参考: http://www.programfan.com/
0 0
- 二叉树的删除
- 删除二叉树的节点
- 二叉树的删除原代码
- 二叉查找树的删除
- 平衡二叉树的删除
- 二叉树的删除javascript
- 二叉树节点的删除
- 二叉树的节点删除
- 二叉搜索树的删除
- 二叉树的删除策略
- 二叉树的查找删除
- 二叉搜索树的查找、插入、删除
- 二叉查找树的删除操作
- 二叉搜索树的插入和删除
- 查找二叉树删除节点的操作
- 排序二叉树的插入和删除
- 二叉树的两种删除方式
- 二叉查找树中节点的删除。
- java集合-EnumMap与EnumSet
- poj2083
- 1001: Gingers and Mints
- POJ 3616
- Java 小白编程遇到的问题
- 二叉树的删除
- 算法动态规划问题之矩阵连乘
- 商品搜索引擎---分词(插件介绍与入门实例)
- LeetCode[Array]----3Sum
- hrbust2291
- nyoj 68三点顺序(矢量叉积)
- 腾讯前端实习生(一面)
- 隐式类型转换
- Struts2中自定义类型转换器