排序二叉树节点的删除
首先先看看这个删除节点12后的树,还要保证该平衡二叉树的特性保持不变
删除节点详细分为三类:
第一类.所删除的节点是叶子节点,这样就可以先遍历这个树,然后找到需要删除的节点,把它free掉就好
第二类:就是所删除的节点只有一个左孩子,或者只有一个右孩子,则把该节点的孩子变为它父亲的孩子 ,然后删除这个结点
在这个例子把28删除,就是把30连接到12上
第三类:就是最麻烦的一类,假如我们要删除节点12,直接删除就会破坏了排序二叉树的结构,那么我们想到一个方法,就是把这类转换成第一类,那么重点来了,我们找到要删除的结点后,找到在这个节点左子树的最右的节点或者右子树的最左侧的节点,把这个节点的值覆盖到要删除的节点上,然后删除左子树的最右的节点或者右子树的最左侧的节点,
我们看这个例子:要删除12 先找到以12位根的左子树的最右的节点 就是数字6 ,把6覆盖到节点·12,然后删除节点6
或者找到右子树的最左边的节点 就是该树上的28,把28覆盖到节点12上,再删除28,就变成了第二类删除
代码如下:核心函数Search 和 DelNode
#include<stdio.h>
#include<stdlib.h>typedef struct node
{int nValue;struct node *pLeft;struct node *pRight;
}BinatyTree;void InsertNode(BinatyTree **pTree,int nNum)
{BinatyTree *pTemp = NULL;pTemp = (BinatyTree*)malloc(sizeof(BinatyTree));pTemp->nValue = nNum;pTemp->pLeft = NULL;pTemp->pRight = NULL;//空树if(*pTree == NULL){*pTree = pTemp;return;}//非空树BinatyTree *pNode = *pTree;while(1){if(nNum > pNode->nValue){//去右侧if(pNode->pRight == NULL){pNode->pRight = pTemp;return;}//向右走pNode = pNode->pRight;}else if(nNum < pNode->nValue){//去左侧if(pNode->pLeft == NULL){pNode->pLeft = pTemp;return;}pNode = pNode->pLeft;}else{printf("数据错误.\n");return;}}
}void CreateBST(int arr[],int nLength,BinatyTree **pTree)
{if(arr == NULL || nLength <=0)return;int i;for(i = 0;i<nLength;i++){InsertNode(pTree,arr[i]);}
}void Search(BinatyTree *pTree,int nNum,BinatyTree **pDel,BinatyTree **pFather)
{while(pTree != NULL){if(pTree->nValue == nNum){*pDel = pTree;return;}else if(pTree->nValue > nNum){*pFather = pTree;pTree = pTree->pLeft;}else {*pFather = pTree;pTree = pTree->pRight;}}
}void DelNode(BinatyTree **pTree,int nNum)
{if(*pTree == NULL)return;//查找BinatyTree *pDel = NULL;BinatyTree *pFather = NULL;Search(*pTree,nNum,&pDel,&pFather);if(pDel == NULL)return;//分析情况//两个BinatyTree *pMark = NULL;if(pDel->pLeft != NULL && pDel->pRight!= NULL){//找左的最右pMark = pDel;//向左走一步pFather = pDel;pDel = pDel->pLeft;while(pDel->pRight != NULL){pFather = pDel;pDel = pDel->pRight;}//值覆盖pMark->nValue = pDel->nValue;}//被删除节点是根节点if(pFather == NULL){*pTree = pDel->pLeft ? pDel->pLeft : pDel->pRight;free(pDel);pDel = NULL;return;}//被删除节点非根if(pDel == pFather->pLeft){pFather->pLeft = pDel->pLeft ? pDel->pLeft:pDel->pRight;free(pDel);pDel = NULL;return;}else{pFather->pRight = pDel->pLeft ? pDel->pLeft:pDel->pRight;free(pDel);pDel = NULL;return;}
}void Traversal(BinatyTree *pTree)
{if(pTree == NULL)return;Traversal(pTree->pLeft);printf("%d ",pTree->nValue);Traversal(pTree->pRight);
}int main()
{int arr[] = {10,38,2,100,80,15,1,8,16};BinatyTree *pTree = NULL;CreateBST(arr,sizeof(arr)/sizeof(arr[0]),&pTree);Traversal(pTree);printf("\n");DelNode(&pTree,10);Traversal(pTree);return 0;
}
排序二叉树节点的删除相关推荐
- 一步一步写算法(之排序二叉树删除-1)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 相比较节点的添加,平衡二叉树的删除要复杂一些.因为在删除的过程中,你要考虑到不同的情况,针对每 ...
- 研磨数据结构与算法-13删除二叉树节点
节点: /* * 二叉树节点 */ public class Node { //数据项 public long data; //数据项 public String sData; //左子节点 publ ...
- 数据结构 day07 基础知识学习 (二叉树 的 前中后遍历 ,插入节点,删除叶子节点, 二叉树的节点个数 )
一.今天有点迷. 二.希望大家看的懂代码 ,我已经很努力写注释了. 三.这次的知识很基础 ,(老师关于 二叉树节点删除的哪里 讲的有点差 ,主要是讲之前没有打好框架 (关于父节点的定义 ) ...
- 牛牛有一棵n个节点的二叉树,该二叉树每个节点的权值为1。牛牛想要删掉该树其中的k层节点,删除序列为a1,a2...ak。 如有一棵二叉树,删除其中的第3层节点
题目:牛牛有一棵n个节点的二叉树,该二叉树每个节点的权值为1.牛牛想要删掉该树其中的k层节点,删除序列为a1,a2-ak. 如有一棵二叉树,删除其中的第3层节点 思路: 层序遍历,遍历时对节点依次进行 ...
- 一步一步写算法(之排序二叉树删除-3)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 3 普通节点的删除 3.1 删除的节点没有左子树,也没有右子树 测试用例1: 删除节点6 /* ...
- 一步一步写算法(之排序二叉树删除-2)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 2.4 删除节点的左右子树都存在,此时又会分成两种情形 1)左节点是当前左子树的最大节点,此时 ...
- java实现排序二叉树
* 二叉树排序算法看似很简单,特别是看到其他博客写的实现代码,但是如果把细节各种情况考虑进去,还是不容易的. * 数据使用链式二叉树来存储,在增加节点的时候,小的在父节点的左边,大的在父节点的右边.刚 ...
- 数据结构之二叉搜索树/二叉查找数/有序二叉树/排序二叉树
概念~ 二叉查找树(英语:Binary Search Tree),也称二叉搜索树.有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree), ...
- 一步一图一代码之排序二叉树
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong/) 属性: ①若它的左子树不为空,则左子树上所有节点的值均小于它的根节点的值. ②若它的右子树不为空,则右子树上所 ...
最新文章
- 计算机进桌面后反复重启,我的电脑一插网线就自动重启。到界面之后又马上重启。一直循环。...
- OOP 中的 方法调用、接口、鸭式辩型、访问者模式
- python 格式化工具_Google的Python代码格式化工具YAPF详解
- linux access源码,从零开始学习Linux:Day04 源码安装Nginx 。acess/status/referer
- (01)VTK读取OBJ格式模型
- 电动牙刷C语言程序,电动牙刷的日常维护
- 一种人脸识别活体检测方法
- html鼠标移上去变成箭头,js实现鼠标移动到div上变成箭头
- 【游戏】——微信打飞机
- canvas 实现图片局部模糊_HTML5 Canvas图片马赛克模糊动画
- 【RabbitMQ】java.lang.NoClassDefFoundError: org/springframework/util/backoff/BackOff
- 国产银河数字式电子计算机是属于什么,邱桂香老师-计算机基础.ppt
- 小猫爪:i.MX RT1050学习笔记2-下载
- 鱼眼参数的数值计算优化方法
- 汽车ISP的“去留”之谜
- [家里蹲大学数学杂志]第266期中南大学2013年高等代数考研试题参考解答
- java生成PDF 导出
- SuperMap GIS点云数据处理QA
- 适合程序员表白的情话【保你脱单】
- 【iOS沉思录】Objective-C语言消息传递机制三道防线:消息转发机制详解
热门文章
- 计算机中单元格地址如何命名,单元格命名_怎样给单元格重新命名或是删除单元格名称_vba...
- C语言 如何给结构体中的数组赋值
- WIN10系统让服务程序自启动
- nagios安装与配置教程(详细版)【入门教程】2020-11-16
- java中有关hashset_java中HashSet详解
- 叮,你收到一份来自CNCF的云原生景观简介
- java面试突击_两个月!终于把《JavaGuide面试突击》v3.0肝出来了!
- 机器学习-Boosting(AdaBoost、GBDT)
- 回应张逸老师(二)小甜甜和牛夫人?
- 前端项目实战30-多加一个列表表示详情