1. 设计一个算法将顺序表L中所有小于0的整数放前半部分,大于等于0的整数放在后半部分
  2. 二叉树的删除

设计一个算法将顺序表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. 先找到要删除的节点,并记录该节点属于左节点还是右节点
  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 &&current.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步相同,还是先找到要删除的节点.

  1. 若该节点的右节点为空,则将左节点提升为父亲节点
  2. 若该节点的左节点为空,则将右节点提升为父亲节点
  3. 从以上两点可得知将剩余子节点提升为父亲节点
  4. 根据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

寻找具有有两个子节点的节点的替补节点

如要删除该节点,要么被代替的节点需要具备以下特征:

  1. 比该节点的左节点大
  2. 比该节点的右节点小

如果无法满足以上两点,情况将变的更加复杂.

如要删除节点20,那么节点30则是最佳替补(这里如果有个节点25则更加说明这个情况).
节点25比15大,比30小.

中序后继:由于25在20后面,则成25为节点20的后继.所以当遇到要删除有两个节点的节点时,首要目标就是找到该节点的后继节点,以上的铺垫1内容就是为这里准备的。查找后继节点规则:

  1. 如果有左节点,则最深处左节点为后继节点
  2. 如果没有左节点,则第一个右节点为后继节点(如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;}

删除中序后继节点

找到中序后继后,还要处理一些事情.来考虑一个中序后继的一些特点:

  1. 一定没有左节点(如果有就不是后继了,可以继续往左节点找)
  2. 但有可能会有右节点

所以要按照情况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;

可以看到删除一个后继的动作相当的复杂

  1. 改变了其右节点的父亲节点
  2. 改变了其右节点
  3. 改变其父亲节点
  4. 改变了其左节点

完整删除代码示例(来自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 &&current.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相关推荐

  1. Interview:算法岗位面试—10.12上午—上海某科技公司图像算法岗位(偏图像算法,互联网AI行业)技术面试考点之LoR逻辑回归的底层代码实现、特征图计算公式

    ML岗位面试:10.12上午-上海某科技公司图像算法岗位(偏图像算法,互联网AI行业)技术面试考点之LoR逻辑回归的底层代码实现.特征图计算公式 Interview:算法岗位面试-10.12上午-上海 ...

  2. 2011年12月份学习总结,在PE的前端标准思考和萌芽

    2011年12月份学习总结,创建日期:2012-01-03 22:21:31,有删减. 早年的一篇总结,记录对于前端标准的一些思考和萌芽工作: 对于当时的前端标准,始于2011年,在2013~2014 ...

  3. 【论文研读】-基于对偶种群的约束多目标优化进化算法-补充材料

    基于对偶种群的约束多目标优化进化算法-补充材料 Supplementary File of "A Dual-Population based Evolutionary Algorithm f ...

  4. 笔记2011.7.12

    union V {     struct X {         unsigned char s1:2;         unsigned char s2:3;         unsigned ch ...

  5. 【Android 内存优化】内存抖动 ( 垃圾回收算法总结 | 分代收集算法补充 | 内存抖动排查 | 内存抖动操作 | 集合选择 )

    文章目录 一. 垃圾回收算法总结 二. 分代收集算法补充 三. 查看 Java 虚拟机 四. 获取 Android 应用可使用最大内存 五. 内存抖动标志 六. 排查内存抖动 七. 常见的造成内存抖动 ...

  6. Keras之DNN:利用DNN算法【Input(8)→12+8(relu)→O(sigmoid)】利用糖尿病数据集训练、评估模型(利用糖尿病数据集中的八个参数特征预测一个0或1结果)

    Keras之DNN:利用DNN算法[Input(8)→12+8(relu)→O(sigmoid)]利用糖尿病数据集训练.评估模型(利用糖尿病数据集中的八个参数特征预测一个0或1结果) 目录 输出结果 ...

  7. 按冯诺依曼提出的计算机类型,2011年12月24日计算机一级考试题目广西

    <2011年12月24日计算机一级考试题目广西>由会员分享,可在线阅读,更多相关<2011年12月24日计算机一级考试题目广西(13页珍藏版)>请在人人文库网上搜索. 1.全国 ...

  8. 美光科技股价上涨13% 创下自2011年12月以来最大单日涨幅

    [TechWeb]6月27日消息,据国外媒体报道,当地时间周三,美光科技股价上涨13%,至37.04美元,创下自2011年12月22日以来的最大单日涨幅. 此前,美光科技表示,已经对华为恢复了部分芯片 ...

  9. 海南大学计算机学院唐朝胜,海南大学2011年12月新增博、硕导名单

    海南大学2011年12月新增博.硕导名单本站小编 免费考研网/2016-01-29 附件1 博士研究生指导教师名单 序号    姓  名    所在学科.专业    备  注 1    江行玉    ...

最新文章

  1. 计算两个日期相差的天数
  2. OpenGL编程指南10:组合运动示例1—创建太阳系模型
  3. 【shell脚本学习-3】
  4. bz1968 1968: [Ahoi2005]COMMON 约数研究
  5. [笔记一]Essential JavaScript Design Patterns For Beginners
  6. vue 中样式的绑定
  7. Java游戏编程技术-1
  8. 如何完全删除数据库 任何版本 注册表删除法
  9. 数据脱敏:k-anonymity,l-diversity,t-closeness
  10. python生成所有6位数的数字手机验证码(000000-999999)
  11. 传统零售业务分析指标整理
  12. 使 abbr 元素适用于触摸屏、键盘和鼠标
  13. linux 卸载lxde,UBUNTU最小化搭建LXDE桌面环境
  14. VMware Workstation Ubuntu 20.04 LTS无法连接网络问题
  15. 个人管理:“唐僧”之五项修炼
  16. 十六周项目一----冒泡排序
  17. 为什么 DNS 使用 UDP 协议
  18. “薪水”种种表达方法
  19. ctime()函数以及time()使用
  20. 2019辽宁公务员考试行测常识大全:公务员常识40000问(四十六)

热门文章

  1. [react] react中什么是受控组件?
  2. React开发(244):dva概念8router
  3. [html] 说说你对HTML5中“一次编写,全体使用”的理解
  4. [jQuery] jQuery与jQuery UI有啥区别?
  5. [vue] 怎么访问到子组件的实例或者子元素?
  6. 前端学习(2867):vue3数据劫持解析2
  7. [js] 根据元素ID遍历树形结构,查找到所有父元素ID
  8. 工作306:.sync解决子组件改变自身值 父组件也改变自身数值
  9. 前端学习(2829):block标签的使用
  10. 前端学习(2709):重读vue电商网站29之左侧菜单栏