算法补充 2011-9-12

 

  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这些节点

image

  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.二叉排序树的中序遍历

image

如上图

二叉排序树的中序遍历的值是一个升序排列,以上结果为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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/422770.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言进阶深度学习记录】三十八 C/C++语言中的函数声明与函数定义

文章目录1 函数的声明和定义1.1 代码分析2 总结1 函数的声明和定义 声明的意义在于告诉编译器程序单元的存在。只是告诉编译器它存在但是不在声明这里定义&#xff0c;有可能在当前文件中的其他地方或者其他文件中定义。如果在它还没有被定义之前就使用它&#xff0c;会导致编…

ASP.NET MVC3 系列教程 - 部署你的WEB应用到IIS 6.0

I:ASP.NET MVC3 部署的前期工作 1.确认部署的服务器操作系统环境 首先我们确认服务器的操作系统版本可以从系统命令行工具里输入: systeminfo 获取相关操作系统信息例如然后再确认IIS版本信息 -> 打开IIS管理工具即可接着确认.NET Framework的版本可以在系统命令行工具执行:…

【C语言进阶深度学习记录】三十九 C语言中的可变参数(参数可变的函数)

用过printf()函数的热都知道&#xff0c;printf的参数可以有多个&#xff0c;它是可变的&#xff0c;根据我们输出参数的类型以及个数的不同来确定参数。今天来学习C语言中参数可变的函数是如何实现的。 文章目录1 可变参数2 总结1 可变参数 首先我们要明白一点&#xff0c;在…

Linux 安装 OpenOffice

继续弃W从L的奋斗&#xff01;哈哈 在RedHat 6 上安装 OpenOffice。 首先在官网上下载OpenOffice的软件包 100多M。软件包名为&#xff1a;OOo_3.3.0_Linux_x86_install-rpm_en-US.tar.gz 下好后开始安装软件&#xff1a;1 解压 tar xjvf OOo_3.3.0_Linux_x86_install…

【离散数学中的数据结构与算法】一 最大公约数与最小公倍数之间的关系

文章目录1 算数基本定理2 最大公约数3 最小公倍数4 性质5 推论1 算数基本定理 设正整数 n>1&#xff0c; 则 n 可唯一地表示为&#xff1a; 其中 p1<p2<,…, <ps 是 s 个相异的素数&#xff0c; 指数ki都是正整数。 此定理又称作唯一析因定理&#xff08;unique f…

Item 添加事件 list grally等

mainListView.setOnItemClickListener (new OnItemClickListener(){ public void onItemClick(AdapterView<?> parent,View v,int position,long id){ } });转载于:https://www.cnblogs.com/sode/archive/2011/09/25/2189845.html

【离散数学中的数据结构与算法】二 欧几里得算法与裴蜀等式

欧几里得算法是计算两个数最大公因子算法。又称辗转相除法。本文将学习为什么辗转相除法可以求得两个数的最大公因子。同时也可以根据最大公因子计算两个数的最小公倍数。 文章目录1 欧几里得算法的理论基础1.1 欧几里得算法&#xff08;辗转相除法&#xff09;2 裴蜀等式&…

数据库-存储过程-游标-函数

一、存储过程 SQL99标准提出的SQL-invoked-rountines的概念&#xff0c;它开分为存储过程与函数&#xff0c;这里首先介绍存储过程 存储过程分为三类&#xff1a;系统存储过程(如&#xff1a;sp_help)、自定义存储过程、扩展存储过程 存储过程可以理解为一个SQL语句块&am…

【离散数学中的数据结构与算法】四 加法法则与乘法法则

文章目录1 加法法则2 乘法法则3 例子3.1 例一3.2 例二3.3 例三4 总结1 加法法则 加法法则&#xff1a; 设事件 A 有 m 种产生方式&#xff0c; 事件 B 有n 种产生方式&#xff0c;则当 A 与 B 产生的方式不重叠时&#xff0c;“事件 A 或 B 之一” 有 mn 种产生方式。 加法法…

实现上移的存储过程

--上移存储过程 create proc sp_sort id int as declare SortID int --排序位置 declare TempSortID int --临时排序位置 declare TempID int --临时编号 begin transaction select SortIDSortID from [User] where [ID]ID --找出想修改顺序的用户的当前当前排序 select Tem…

前端学习(310):清除浮动的方法

我们经常把高度塌陷问题也叫做常见的几种清除浮动的方法 高度塌陷问题—父元素高度自适应&#xff0c;子元素float后&#xff0c;造成父元素高度为0&#xff0c;就叫做高度塌陷问题 给父元素一个高度 缺点&#xff1a;无法高度自适应 父元素{overflow:hidden;} 缺点&#xf…

【离散数学中的数据结构与算法】五 排列与组合一

在leetcode刷题过程中&#xff0c;遇到过很多关于排列组合的问题。弄清楚排列组合的相关原理&#xff0c;是非常有用处的。 文章目录1 问题2 排列-有序选取2.1 重复选取-可重排列2.2 不重复选取-排列2.21 全排列3 例题4 总结1 问题 设集合S包含n个元素&#xff0c;从S中选取r个…

Google Maps 地址转化成坐标

http请求格式http://maps.google.com/maps/geo?q查询关键字&outputkml(输出格式可以 为xml kml json)&oeutf8&sensortrue或者false&key你的apikey示例http://maps.google.com/maps/geo?q湖南大学软件学院&outputkml&keyabcdefg(api key)输出kml文件如…

【离散数学中的数据结构与算法】六 排列与组合二

接着上一篇学习&#xff1a;【离散数学中的数据结构与算法】五 排列与组合一 上一篇文章主要学习了可重复选取的可重排列和不可重复选取的排列。他们都是在n个不同的对象中选取。 今天我们俩学习的是&#xff0c;当这个n个对象中有相同的元素的时候&#xff0c;排列的相关定理…

sql 2008 使用output避免数据修改后的二次查询

表a (f1 primary key,f2,f3), 表b (f1,f3,f4)现要根据表b修改表a中的相应字段的值&#xff0c;并将修改过的值显示出来&#xff0c;一般用法&#xff1a;1 update a from b set a.f3b.f3 where a.f1b.f12 select a.f1,f2,f3 from a where a.f1 in (select f1 from b)根据sql的…

【离散数学中的数据结构与算法】七 排列与组合三

前两篇文章学习了不可重复选取的排列与可重复选取的可重排列。本篇文章开始学习组合的相关定理。 文章目录1 组合1.1 组合的计算公式2 总结1 组合 跟排列一样。组合也分为不重复选取的组合&#xff0c;与可重复选取的可重组合。本节内容主要学习不可重复选取的组合 从 n 个不…

Silverlight4.0教程之WebBrowser控件(Silverlight内置HTML浏览器控件)

微软于PDC2009上发布Silverlight 4 Beta版&#xff0c;微软在Silverlight 4版本中处理了约8000个的Silverlight终端用户的请求&#xff0c;加入了一系列另开发人员兴奋的新特性&#xff0c;最突出的主要体现在几个方面&#xff1a; 开发工具增强&#xff1a;Visual Studio 2010…