【搜索】二叉搜索树
2018-11-20 03:19:37来源:博客园 阅读 ()
概念:二叉搜索树可以是空树,也可以是满足一个节点的左子节点逻辑上小于该节点且右子节点逻辑上大于等于该节点的二叉树,同时其左右子树也满足这个条件。
查询原理:从根节点开始查询,如果节点为null则查询失败,如果目标值小于节点值,则查询左子树,如果目标值大于节点值,则查询右子树,如果目标值等于节点值,则查询成功。
添加原理:从根节点开始查询,如果节点为null,则把新节点添加到该处,如果目标值小于节点值,则查询左子树,如果目标值大于节点值,则查询右子树。
删除原理:待删除节点分三中情况
1)没有子节点:只需将待删除节点的父节点指向待删除节点的引用赋值为null
2)只有一个子节点:只需将待删除节点的父节点指向待删除节点的引用赋值为待删除节点的子节点的引用
3)有两个节点:需要将待删除节点替换为待删除节点中序遍历的后继节点
/** * 搜索二叉树 * @author qqx * * @param <T> */ public class BinarySearchTree<T> { //根节点 private TreeNode root; /** * 查询一个值是否存在 * @param value * 待查询的值 * @return */ public boolean exist(T value) { TreeNode currentNode = root; if (currentNode == null) return false; else { while (((Comparable<T>) currentNode.value).compareTo(value) != 0) { if (((Comparable<T>) currentNode.value).compareTo(value) > 0) currentNode = currentNode.leftNode; else currentNode = currentNode.rightNode; if (currentNode == null) return false; } } return true; } /** * 添加一个值到搜索二叉树 * @param value * @return */ public BinarySearchTree<T> add(T value) { TreeNode currentNode = root; TreeNode newNode = new TreeNode(value); if (currentNode == null) root = newNode; else { while (true) { if (((Comparable<T>) currentNode.value).compareTo(value) > 0) { if (currentNode.leftNode != null) currentNode = currentNode.leftNode; else { currentNode.leftNode = newNode; break; } } else { if (currentNode.rightNode != null) currentNode = currentNode.rightNode; else { currentNode.rightNode = newNode; break; } } } } return this; } /** * 删除搜索二叉树中一个值 * @param value * @return * @throws Exception */ public BinarySearchTree<T> delete(T value) throws Exception { //待删除的节点 TreeNode currentNode = root; //待删除节点的父节点 TreeNode parentNode = root; //待删除节点是否为待删除节点的父节点的左节点 boolean isLeftNode = false; if (root == null) throw (new Exception("空树删除异常")); //计算待删除节点的父节点,待删除节点是否为待删除节点的父节点的左节点 while (((Comparable<T>) currentNode.value).compareTo(value) != 0) { parentNode=currentNode; if (((Comparable<T>) currentNode.value).compareTo(value) > 0) { currentNode = currentNode.leftNode; isLeftNode=true; } else { currentNode = currentNode.rightNode; isLeftNode=false; } if (currentNode == null) throw (new Exception("删除节点不存在异常")); } //待删除节点没有子节点 if((currentNode.leftNode==null)&&(currentNode.rightNode==null)) { if(currentNode==parentNode) root=null; else if(isLeftNode) parentNode.leftNode=null; else parentNode.rightNode=null; } //待删除节点只有一个子节点 else if((currentNode.leftNode==null)||(currentNode.rightNode==null)) { //待删除节点是根节点 if(currentNode==parentNode) { if(currentNode.leftNode==null) root=currentNode.rightNode; else root=currentNode.leftNode; } else if(isLeftNode) { if(currentNode.leftNode==null) parentNode.leftNode=currentNode.rightNode; else parentNode.leftNode=currentNode.leftNode; } else { if(currentNode.leftNode==null) parentNode.rightNode=currentNode.rightNode; else parentNode.rightNode=currentNode.leftNode; } } //待删除节点有两个子节点 else { //待删除节点在中序遍历中的后继节点 TreeNode sequenceNode=currentNode.rightNode; //待删除节点在中序遍历中的后继节点的父节点 TreeNode sequenceParentNode=currentNode; //计算待删除节点在中序遍历中的后继节点,待删除节点在中序遍历中的后继节点的父节点 while(sequenceNode.leftNode!=null) { sequenceParentNode=sequenceNode; sequenceNode=sequenceNode.leftNode; } //待删除节点在中序遍历中的后继节点不是待删除节点的右子节点 if(sequenceParentNode!=currentNode) { sequenceParentNode.leftNode=sequenceNode.rightNode; sequenceNode.rightNode=currentNode.rightNode; } if(currentNode==root) { root=sequenceNode; root.leftNode=currentNode.leftNode; } else if(isLeftNode) { parentNode.leftNode=sequenceNode; sequenceNode.leftNode=currentNode.leftNode; } else { parentNode.rightNode=sequenceNode; sequenceNode.leftNode=currentNode.leftNode; } } return this; } @Override public String toString() { StringBuilder stringBuilder=new StringBuilder(); inorderTraversal(stringBuilder,root); return stringBuilder.toString(); } /** * 二叉树的中序遍历 */ private void inorderTraversal(StringBuilder stringBuilder,TreeNode node) { if(node!=null) { inorderTraversal(stringBuilder,node.leftNode); stringBuilder.append(node.value); stringBuilder.append(" "); inorderTraversal(stringBuilder,node.rightNode); } } private class TreeNode { private T value; private TreeNode leftNode; private TreeNode rightNode; public TreeNode() { super(); } public TreeNode(T value) { this.value = value; } public TreeNode(T value, TreeNode leftNode, TreeNode rightNode) { super(); this.value = value; this.leftNode = leftNode; this.rightNode = rightNode; } @Override public String toString() { return "TreeNode [value=" + value + ", leftNode=" + leftNode.value + ", rightNode=" + rightNode.value + "]"; } } }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- JAVA自定义注解 2020-06-01
- DDD之2领域概念 2020-05-30
- LeetCode 面试题55 - I. 二叉树的深度 2020-05-22
- LeetCode 104. 二叉树的最大深度 2020-05-22
- LeetCode 面试题33. 二叉搜索树的后序遍历序列 2020-05-22
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash