算法补充 2011-9-12
- 设计一个算法将顺序表L中所有小于0的整数放前半部分,大于等于0的整数放在后半部分
- 二叉树的删除
设计一个算法将顺序表L中所有小于0的整数放前半部分,大于等于0的整数放在后半部分
思路:从左侧找出>0的元素,从右侧找出<=0的元素,然后进行交换
static void Move(SqList &l) {int i=0,j=l.length-1;while(i<j){//position from left to rightwhile(i<j && l.elem[i]<0)i++;//position from right to leftwhile(i<j && l.elem[j]>=0)j--;//swapif(i<j){int temp=l.elem[i];l.elem[i]=l.elem[j];l.elem[j]=temp;}} }
二叉树的删除
情况1:删除没有子节点的节点
即删除6,7,8,9,2这些节点
- 先找到要删除的节点,并记录该节点属于左节点还是右节点
- 判断要删除的节点是否为没有子节点,如果确实没有的话,就将其父节点的其中的一个左右节点置空
执行第1步,查找节点如果current不为空则执行第2步
Node current = root;Node parent = root;boolean isLeftChild = true;while(current.iData != key) // search for node{parent = current;if(key < current.iData) // go left?{isLeftChild = true;current = current.leftChild;}else // or go right?{isLeftChild = false;current = current.rightChild;}if(current == null) // end of the line,return false; // didn't find it} // end while// found node to delete
执行第2步,判断左右节点均未空
// if no children, simply delete it if(current.leftChild==null &¤t.rightChild==null){if(current == root) // if root,root = null; // tree is emptyelse if(isLeftChild)parent.leftChild = null; // disconnectelse // from parentparent.rightChild = null;}
情况2:有一个子节点的节点
第1步如情况1的第1步相同,还是先找到要删除的节点.
- 若该节点的右节点为空,则将左节点提升为父亲节点
- 若该节点的左节点为空,则将右节点提升为父亲节点
- 从以上两点可得知将剩余子节点提升为父亲节点
- 根据isLeftChild标志判断删除的节点是否为左节点
执行步骤1和步骤4
if(current.rightChild==null)if(current == root)root = current.leftChild;else if(isLeftChild)parent.leftChild = current.leftChild;elseparent.rightChild = current.leftChild;
执行步骤2和步骤4
// if no left child, replace with right subtree if(current.leftChild==null)if(current == root)root = current.rightChild;else if(isLeftChild)parent.leftChild = current.rightChild;elseparent.rightChild = current.rightChild;
情况3:删除有两个子节点的节点
铺垫:
1.查找二叉排序树的最大值和最小值
因为二叉树的的节点总是大于左节点,小于右节点的,所以顺着左节点总是能找到最小值,同理顺着右节点总是能找到最大值
public Node getMin() { Node current = root; Node last; while(current!=null) {last=current;current = current.leftChild; } return last; } public Node getMax() { Node current = root; Node last; while(current!=null) {last=current;current = current.rightChild; } return last; }
2.二叉排序树的中序遍历
如上图
二叉排序树的中序遍历的值是一个升序排列,以上结果为15,20,25,30,50,60,70
寻找具有有两个子节点的节点的替补节点
如要删除该节点,要么被代替的节点需要具备以下特征:
- 比该节点的左节点大
- 比该节点的右节点小
如果无法满足以上两点,情况将变的更加复杂.
如要删除节点20,那么节点30则是最佳替补(这里如果有个节点25则更加说明这个情况).
节点25比15大,比30小.
中序后继:由于25在20后面,则成25为节点20的后继.所以当遇到要删除有两个节点的节点时,首要目标就是找到该节点的后继节点,以上的铺垫1内容就是为这里准备的。查找后继节点规则:
- 如果有左节点,则最深处左节点为后继节点
- 如果没有左节点,则第一个右节点为后继节点(如50的后继节点为60)
以下代码体现了以上2个步骤
private Node getSuccessor(Node delNode){Node successorParent = delNode;Node successor = delNode;Node current = delNode.rightChild; // go to right childwhile(current != null) // until no more{ // left children,successorParent = successor;successor = current;current = current.leftChild; // go to left child}return successor;}
删除中序后继节点
找到中序后继后,还要处理一些事情.来考虑一个中序后继的一些特点:
- 一定没有左节点(如果有就不是后继了,可以继续往左节点找)
- 但有可能会有右节点
所以要按照情况2只有右节点的原则处理该右继节点
链接中序后继的右节点
即要删除的节点的右节点变成了中序后继节点的右节点了
所以在getSuccessor方法中while循环结束后,还需要做以下处理
if(successor != delNode.rightChild) // right child,{ // make connectionssuccessorParent.leftChild = successor.rightChild;successor.rightChild = delNode.rightChild;}
链接中序后继的左节点
Node successor = getSuccessor(current);// connect parent of current to successor instead if(current == root)root = successor; else if(isLeftChild)parent.leftChild = successor; elseparent.rightChild = successor;// connect successor to current's left child successor.leftChild = current.leftChild;
可以看到删除一个后继的动作相当的复杂
- 改变了其右节点的父亲节点
- 改变了其右节点
- 改变其父亲节点
- 改变了其左节点
完整删除代码示例(来自Java数据结构和算法)
public boolean delete(int key) // delete node with given key{ // (assumes non-empty list)Node current = root;Node parent = root;boolean isLeftChild = true;while(current.iData != key) // search for node{parent = current;if(key < current.iData) // go left?{isLeftChild = true;current = current.leftChild;}else // or go right?{isLeftChild = false;current = current.rightChild;}if(current == null) // end of the line,return false; // didn't find it} // end while// found node to delete// if no children, simply delete itif(current.leftChild==null &¤t.rightChild==null){if(current == root) // if root,root = null; // tree is emptyelse if(isLeftChild)parent.leftChild = null; // disconnectelse // from parentparent.rightChild = null;}// if no right child, replace with left subtreeelse if(current.rightChild==null)if(current == root)root = current.leftChild;else if(isLeftChild)parent.leftChild = current.leftChild;elseparent.rightChild = current.leftChild;// if no left child, replace with right subtreeelse if(current.leftChild==null)if(current == root)root = current.rightChild;else if(isLeftChild)parent.leftChild = current.rightChild;elseparent.rightChild = current.rightChild;else // two children, so replace with inorder successor{// get successor of node to delete (current)Node successor = getSuccessor(current);// connect parent of current to successor insteadif(current == root)root = successor;else if(isLeftChild)parent.leftChild = successor;elseparent.rightChild = successor;// connect successor to current's left childsuccessor.leftChild = current.leftChild;} // end else two children// (successor cannot have a left child)return true; // success} // end delete() // -------------------------------------------------------------// returns node with next-highest value after delNode// goes to right child, then right child's left descendentsprivate Node getSuccessor(Node delNode){Node successorParent = delNode;Node successor = delNode;Node current = delNode.rightChild; // go to right childwhile(current != null) // until no more{ // left children,successorParent = successor;successor = current;current = current.leftChild; // go to left child}// if successor notif(successor != delNode.rightChild) // right child,{ // make connectionssuccessorParent.leftChild = successor.rightChild;successor.rightChild = delNode.rightChild;}return successor;}
转载于:https://www.cnblogs.com/Clingingboy/archive/2011/09/12/2173981.html
算法补充 2011-9-12相关推荐
- Interview:算法岗位面试—10.12上午—上海某科技公司图像算法岗位(偏图像算法,互联网AI行业)技术面试考点之LoR逻辑回归的底层代码实现、特征图计算公式
ML岗位面试:10.12上午-上海某科技公司图像算法岗位(偏图像算法,互联网AI行业)技术面试考点之LoR逻辑回归的底层代码实现.特征图计算公式 Interview:算法岗位面试-10.12上午-上海 ...
- 2011年12月份学习总结,在PE的前端标准思考和萌芽
2011年12月份学习总结,创建日期:2012-01-03 22:21:31,有删减. 早年的一篇总结,记录对于前端标准的一些思考和萌芽工作: 对于当时的前端标准,始于2011年,在2013~2014 ...
- 【论文研读】-基于对偶种群的约束多目标优化进化算法-补充材料
基于对偶种群的约束多目标优化进化算法-补充材料 Supplementary File of "A Dual-Population based Evolutionary Algorithm f ...
- 笔记2011.7.12
union V { struct X { unsigned char s1:2; unsigned char s2:3; unsigned ch ...
- 【Android 内存优化】内存抖动 ( 垃圾回收算法总结 | 分代收集算法补充 | 内存抖动排查 | 内存抖动操作 | 集合选择 )
文章目录 一. 垃圾回收算法总结 二. 分代收集算法补充 三. 查看 Java 虚拟机 四. 获取 Android 应用可使用最大内存 五. 内存抖动标志 六. 排查内存抖动 七. 常见的造成内存抖动 ...
- Keras之DNN:利用DNN算法【Input(8)→12+8(relu)→O(sigmoid)】利用糖尿病数据集训练、评估模型(利用糖尿病数据集中的八个参数特征预测一个0或1结果)
Keras之DNN:利用DNN算法[Input(8)→12+8(relu)→O(sigmoid)]利用糖尿病数据集训练.评估模型(利用糖尿病数据集中的八个参数特征预测一个0或1结果) 目录 输出结果 ...
- 按冯诺依曼提出的计算机类型,2011年12月24日计算机一级考试题目广西
<2011年12月24日计算机一级考试题目广西>由会员分享,可在线阅读,更多相关<2011年12月24日计算机一级考试题目广西(13页珍藏版)>请在人人文库网上搜索. 1.全国 ...
- 美光科技股价上涨13% 创下自2011年12月以来最大单日涨幅
[TechWeb]6月27日消息,据国外媒体报道,当地时间周三,美光科技股价上涨13%,至37.04美元,创下自2011年12月22日以来的最大单日涨幅. 此前,美光科技表示,已经对华为恢复了部分芯片 ...
- 海南大学计算机学院唐朝胜,海南大学2011年12月新增博、硕导名单
海南大学2011年12月新增博.硕导名单本站小编 免费考研网/2016-01-29 附件1 博士研究生指导教师名单 序号 姓 名 所在学科.专业 备 注 1 江行玉 ...
最新文章
- 计算两个日期相差的天数
- OpenGL编程指南10:组合运动示例1—创建太阳系模型
- 【shell脚本学习-3】
- bz1968 1968: [Ahoi2005]COMMON 约数研究
- [笔记一]Essential JavaScript Design Patterns For Beginners
- vue 中样式的绑定
- Java游戏编程技术-1
- 如何完全删除数据库 任何版本 注册表删除法
- 数据脱敏:k-anonymity,l-diversity,t-closeness
- python生成所有6位数的数字手机验证码(000000-999999)
- 传统零售业务分析指标整理
- 使 abbr 元素适用于触摸屏、键盘和鼠标
- linux 卸载lxde,UBUNTU最小化搭建LXDE桌面环境
- VMware Workstation Ubuntu 20.04 LTS无法连接网络问题
- 个人管理:“唐僧”之五项修炼
- 十六周项目一----冒泡排序
- 为什么 DNS 使用 UDP 协议
- “薪水”种种表达方法
- ctime()函数以及time()使用
- 2019辽宁公务员考试行测常识大全:公务员常识40000问(四十六)
热门文章
- [react] react中什么是受控组件?
- React开发(244):dva概念8router
- [html] 说说你对HTML5中“一次编写,全体使用”的理解
- [jQuery] jQuery与jQuery UI有啥区别?
- [vue] 怎么访问到子组件的实例或者子元素?
- 前端学习(2867):vue3数据劫持解析2
- [js] 根据元素ID遍历树形结构,查找到所有父元素ID
- 工作306:.sync解决子组件改变自身值 父组件也改变自身数值
- 前端学习(2829):block标签的使用
- 前端学习(2709):重读vue电商网站29之左侧菜单栏