减治法在查找算法中的应用(JAVA)--二叉查找树的查找、插入、删除

减治法在查找算法中的应用

二叉查找树的查找与插入:

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:

(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根节点的值;

(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;

(3)左、右子树也分别为二叉排序树。

对于二叉查找树这里我们介绍查找、插入和删除操作:

这些操作会将问题的规模变成一个更小的二叉树,也运用到了减治法的思想。

查找思路:如果树为空,直接返回,查找失败。反之,将查找值key与根root的值比较,如果相等,则root即为所找;若key < root.v,则继续在左子树查找;若key > root.v,则继续在右子树查找。

public static Node find(int key) {if (root == null) {System.out.println("The tree is empty!");return null;}Node cur = root;while (cur.v != key) {if (key < cur.v) {cur = cur.l;}else {cur = cur.r;}if (cur == null) {return null;}}return cur;

插入思路:基本思想和查找操作类似,如果为空树,直接返回,插入节点即为根节点;否则,比较根节点的值与插入节点的值。注意用parent记录遍历到最后的cur值。

public static Node find(int key) {if (root == null) {System.out.println("The tree is empty!");return null;}Node cur = root;while (cur.v != key) {if (key < cur.v) {cur = cur.l;}else {cur = cur.r;}if (cur == null) {return null;}}return cur;
}
删除思路:删除操作是二叉树操作中最复杂的问题。对于二叉树的删除有一下三种情况:

(1)删除叶子结点。可直接删除,不会影响其他

(2)删除结点有且只有一侧孩子结点。孩子结点覆盖待删除结点,删除孩子结点

(3)删除结点下既有左孩子,又有右孩子。在待删除结点的右孩子下,找到v值最小的,用这个结点覆盖要删除的结点。(这里是因为中序遍历结点的后继结点一定是在右子树中v值最小的结点)

public static boolean delete(int key) {Node cur = root;Node parent = root;boolean hasLeft = true;while (cur != null && cur.v != key) {parent = cur;if (key < cur.v) {cur = cur.l;hasLeft = true;} else {cur = cur.r;hasLeft = false;}}if (cur == null) {return false;}if (cur.l == null && cur.r == null) {/*** 要删除的节点为叶子节点,直接删除* */if (cur == root) {root = null;}if (hasLeft) {parent.l = null;} else {parent.r = null;}} else if (cur.r == null) {/*** 要删除的节点只有左孩子* */if (cur == root) {root = cur.l;}if (hasLeft) {parent.l = cur.l;} else {parent.r = cur.l;}} else if (cur.l == null) {/*** 要删除的节点只有右孩子* */if (cur == root) {root = cur.r;}if (hasLeft) {parent.l = cur.r;}else {parent.r = cur.r;}} else {/*** 要删除的节点既有左孩子又有右孩子* 思路:用待删除节点右子树中的v值最小的结点来替代要删除的节点,然后删除右子树中结点* 右子树中v值最小的节点一定没有左子树,所以删除的这个结点一定是属于叶子节点或只有右子树的节点* */Node directPostNode = getPost(cur);cur.v = directPostNode.v;}return true;
}
private static Node getPost(Node delNode) {Node parent = delNode;Node dir = delNode;Node cur = delNode.r;while (cur != null) {parent = dir;dir = cur;cur = cur.l;}if (dir != delNode.r) {//从树中删除此直接后继节点parent.l = dir.r;dir.r = null;}return dir;
}
完整代码如下:

class Node {int v;Node l;Node r;public Node(int v) {this.v = v;}
}
public class Main {public static Node root;public static Node find(int key) {if (root == null) {System.out.println("The tree is empty!");return null;}Node cur = root;while (cur.v != key) {if (key < cur.v) {cur = cur.l;}else {cur = cur.r;}if (cur == null) {return null;}}return cur;}public static void insert(Node node) {if (root == null) {root = node;return;}Node cur = root;Node parent = root;boolean hasLeft = true;while (cur != null) {parent = cur;if (node.v > cur.v) {cur = cur.r;hasLeft = true;} else {cur = cur.l;hasLeft = false;}}if (hasLeft) {parent.l = node;} else {parent.r = node;}}public static boolean delete(int key) {Node cur = root;Node parent = root;boolean hasLeft = true;while (cur != null && cur.v != key) {parent = cur;if (key < cur.v) {cur = cur.l;hasLeft = true;} else {cur = cur.r;hasLeft = false;}}if (cur == null) {return false;}if (cur.l == null && cur.r == null) {/*** 要删除的节点为叶子节点,直接删除* */if (cur == root) {root = null;}if (hasLeft) {parent.l = null;} else {parent.r = null;}} else if (cur.r == null) {/*** 要删除的节点只有左孩子* */if (cur == root) {root = cur.l;}if (hasLeft) {parent.l = cur.l;} else {parent.r = cur.l;}} else if (cur.l == null) {/*** 要删除的节点只有右孩子* */if (cur == root) {root = cur.r;}if (hasLeft) {parent.l = cur.r;}else {parent.r = cur.r;}} else {/*** 要删除的节点既有左孩子又有右孩子* 思路:用待删除节点右子树中的v值最小的结点来替代要删除的节点,然后删除右子树中结点* 右子树中v值最小的节点一定没有左子树,所以删除的这个结点一定是属于叶子节点或只有右子树的节点* */Node directPostNode = getPost(cur);cur.v = directPostNode.v;}return true;}private static Node getPost(Node delNode) {Node parent = delNode;Node dir = delNode;Node cur = delNode.r;while (cur != null) {parent = dir;dir = cur;cur = cur.l;}if (dir != delNode.r) {//从树中删除此直接后继节点parent.l = dir.r;dir.r = null;}return dir;}public static void preorder(Node node) {System.out.print(node.v + " ");if (node.l != null)preorder(node.l);if (node.r != null)preorder(node.r);}public static void main(String[] args) {/*** 插入* */insert(new Node(20));insert(new Node(10));insert(new Node(30));/*** 查找* */System.out.println(find(20));/*** 删除* */delete(20);/*** 前序遍历* */preorder(root);}
}




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

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

相关文章

Navicat Premium试用期破解方法(转)

转载网址https://blog.csdn.net/Jason_Julie/article/details/82864187 1、按步骤安装Navicat Premium&#xff0c;如果没有可以去官网下载&#xff1a;http://www.navicat.com.cn/download/navicat-premium 2、安装好后下载激活文件&#xff1a;https://pan.baidu.com/s/1kVgT…

减治法在排序算法中的应用(JAVA)--插入排序

一、减治法在排序算法中的应用 插入排序&#xff1a;时间复杂度O(n^2)&#xff0c;虽然和选择、冒泡在最坏的情况下时间复杂度相同&#xff0c;但是插排平均性能在比自身的最差性能快一倍&#xff0c;所以相比选择、冒泡来说&#xff0c;插排要领先于二者。 public class Main…

减治法在求解拓扑排序问题中的应用(JAVA)--有向无环图

减治法在求解拓扑排序问题中的应用 拓扑排序&#xff1a;对于一个有向无环图来说&#xff0c;如果我们能够按照次序列出顶点&#xff0c;使得对于每条边来说&#xff0c;边的起始顶点总是排在边的结束顶点之前&#xff0c;那么这个过程就称为拓扑排序&#xff0c;拓扑排序有解…

Java中string.equalsIgnoreCase(0)与0.equalsIgnoreCase(string)的区别:

string.equalsIgnoreCase("0")&#xff1a;如果string为null,会抛出java.lang.NullPointerException异常。 "0".equalsIgnoreCase(string)&#xff1a;即使string为null也不会抛出异常。 所以一般如果判断一个字符串与一个常量是否相等的时候&#xff0c;应…

减治法在生成全排列中的应用(JAVA)--回溯、Johnson-Trotter算法、自字典序

减治法在生成组合对象问题中的应用 在深入浅出讲算法思想--蛮力法思想分析及应用这篇文章的最优解问题中中已经初步讲解了这类应用&#xff0c;下面我们将使用减治法再次思考这类问题。 1、全排列问题&#xff0c;在数学中求解一个n个数组合的全排列问题会产生n&#xff01;…

减治法在生成子集问题中的应用(JAVA)--递归、二进制反射格雷码

减治法在生成组合对象问题中的应用 生成子集问题&#xff1a;经典的背包问题就是求解一个最优子集的问题&#xff0c;这里我们来讨论一个更简单的问题。对于任意一个集合来说&#xff0c;它都存在2^n个子集&#xff08;一个集合所有的子集集合称为幂集&#xff09;。 1&…

【第九课】MriaDB密码重置和慢查询日志

目录 1、如何进行修改MariaDB的密码2、Mariadb的慢查询日志1、如何进行修改MariaDB的密码 记得root密码的修改方式&#xff1a; [rootlocalhost ~]# mysqladmin -uroot -p123456 password "123123" [rootlocalhost ~]# mysql -uroot -p Enter password: ERROR 1045 …

减治法解决俄式乘法问题(JAVA)

以上是在《算法设计与分析基础》一书中给出的定义。 这种算法只包括折半、加倍、相加这几个操作&#xff0c;在计算时&#xff0c;不需要用九九乘法表 。 同时&#xff0c;这个方法每次都会将计算的规模减少&#xff0c;运用了减治的思想 public class Main {public static…

1.需要对txt存放的测试数据做去重处理,代码如下

采用集合去重&#xff0c;在新文件里逐行写入&#xff0c;达成目的 old_file "D:/testdata/memberId.txt" #old result_file "D:/testdata/memberId_new.txt" #new lines_seen set() out_file open(result_file, "w") f open(old_file, &q…

减治法解决尼姆(Nim)游戏/拈游戏问题(JAVA)

尼姆游戏是一种两个人玩的回合制数学策略游戏。游戏者轮流从一堆棋子&#xff08;一共有好几堆&#xff0c;一次只能从其中一堆拿。&#xff09;&#xff08;或者任何道具&#xff09;中取走一个或者多个&#xff0c;最后不能再取的就是输家。当指定相应数量时&#xff0c;一堆…

jquery中$(document).ready()和window.onload的区别

在Jquery里面&#xff0c;我们可以看到两种写法:$(function(){}) 和$(document).ready(function(){}) 这两个方法的效果都是一样的&#xff0c;都是在dom文档树加载完之后执行一个函数&#xff08;注意&#xff0c;这里面的文档树加载完不代表全部文件加载完&#xff09;。 $(d…

蛮力法在排序算法中的应用(JAVA)--选择排序、冒泡排序

蛮力法在排序算法中的应用 对于一个排序问题&#xff0c;我们能想到的最简单的排序方法就是选择和冒泡 1、选择排序&#xff1a;时间复杂度O(n^2) public class Main {public static void main(String[] args) {int[] a {89, 45, 68, 90, 29, 34, 17};int min;for (int i 0…

PyCherm的常用快捷键总结

、Ctrl Enter&#xff1a;在下方新建行但不移动光标&#xff1b; 2、Shift Enter&#xff1a;在下方新建行并移到新行行首&#xff1b; 3、Ctrl /&#xff1a;注释(取消注释)选择的行&#xff1b; 4、Ctrl Alt L&#xff1a;格式化代码(与QQ锁定热键冲突&#xff0c;关闭Q…

蛮力法在查找算法中的应用(JAVA)--顺序查找

蛮力法在查找算法中的应用 对于查找算法来说&#xff0c;最简单的一个思路就是逐个匹配&#xff0c;直到找到目标元素 顺序查找&#xff1a; public class Main {public static void main(String[] args) {int[] a {89, 45, 68, 90, 29, 34, 17, 0};int k 45;int i 0;a[a.…

Xshell报错“The remote SSH server rejected X11 forwarding request.”

xshell连接centos7&#xff0c;报错&#xff1a;“The remote SSH server rejected X11 forwarding request.” 打开文件/etc/ssh/sshd_config,修改下面的参数 X11Forwarding yes 如果有&#xff0c;那就不用修改 修改xshell连接属性 把勾选去掉即可&#xff01; 参考&#xff…

蛮力法在字符串匹配问题中的应用(JAVA)--朴素模式匹配算法

蛮力法在字符串匹配问题中的应用字符串匹配问题通常是给定一个n个字符组成的串&#xff08;称为文本&#xff09;&#xff0c;一个m&#xff08;m<n&#xff09;个字符的串&#xff08;称为模式&#xff09;&#xff0c;从文本中寻找匹配模式的子串。显然我们需要逐个匹配&a…

蛮力法在求解“最近对”问题中的应用(JAVA)

最近对问题是在计算几何问题中最简单的&#xff0c;是指在一个包含n个点的集合中&#xff0c;找到距离最近的两个点&#xff0c;我们这里只研究二维空间中的版本&#xff0c;高维计算基本类似&#xff0c;区别只在于计算两点之间距离的公式略有不同&#xff0c;下面是标准的欧几…

测试框架有哪些

自动化测试最近几年都是大热&#xff0c;这里结合网上以及自己的经验整理了一些&#xff0c;自动化测试必问的一些题目&#xff0c;为想进入软件测试行业的同学一点帮助。一、如何理解自动化测试&#xff1f; 每个面试自动化测试的&#xff0c;80%会被问到这个。不用太宽泛&…

蛮力法在求解凸包问题中的应用(JAVA)

凸包问题向来是计算几何中最重要的问题之一&#xff0c;许多各式各样的应用大多要么本身就是图凸包问题要么其中一部分需要按照凸包问题解决。 凸集合定义&#xff1a;对于平面上一个点集合&#xff0c;如果集合中的任意两点p和q为端点的线段都属于该集合&#xff0c;那么称这…

人生路上对我影响最大的三位老师

在我的人生路上对我影响最大的三位老师第一位那便可能是我小学一年级到五年级的数学老师&#xff0c;他对我的影响确实是挺大但都是负面的那个老师不怎么负责人经常进来上课都是一身酒味在他四年的教导下以至于我到了五年级了两位数的乘除法都忘的差不多了&#xff0c;其实这也…