数据结构:二叉搜索树(BST)的基本操作
来源:互联网 发布:鸟叔的linux私房菜 编辑:程序博客网 时间:2024/05/16 11:36
概述:
学习过数据结构的童鞋都应该知道,对树的操作是一些最基本的技能(本文是对后面要写B树、B-树、B+树的一个前导,已经熟悉的朋友可以跳过了)。而在树结构中,二叉树又是最基础的。虽然这些知识是比较基础的,不过对于BST的操作中,删除是一个相对比较麻烦的。这对于新手来说可能不太好理解,下面就以BST中节点的删除为主,其他操作为辅的策略来编写本篇文章。希望对你能有所帮助。
本文链接:http://blog.csdn.net/lemon_tree12138/article/details/50366993 -- Coding-Naga
--转载请注明出处
基本操作:
1.插入
public void insert(int _value) { Node node = root; boolean inserted = false; while(!inserted) { if (_value == node.getValue()) { inserted = true; } else if (_value < node.getValue()) { Node leftNode = node.getLeft(); if (leftNode == null) { leftNode = new Node(_value); node.setLeft(leftNode); inserted = true; } else { node = leftNode; } } else { Node rightNode = node.getRight(); if (rightNode == null) { rightNode = new Node(_value); node.setRight(rightNode); inserted = true; } else { node = rightNode; } } } }
2.查找
这里就拿找到一个待删除节点为例作说明。
private Node[] searchRemoveNode(int _value) { Node parentNode = null; Node removeNode = root; while(removeNode != null) { if (removeNode.getValue() == _value) { break; } if (removeNode.getValue() < _value) { parentNode = removeNode; removeNode = removeNode.getRight(); } if (removeNode.getValue() > _value) { parentNode = removeNode; removeNode = removeNode.getLeft(); } } return new Node[]{parentNode, removeNode}; }
3.删除
嗯,重点来了。
关于二叉搜索树的删除是相对比较麻烦的。这是为什么呢?我们知道二叉搜索可以快速查找某一个元素是否存在的原因,是BST遵循了一些规则。而我们麻烦的原因也正因为这个规则。
或许你会说,删除有什么难的。直接记录一下待删除节点的左、右孩子节点,再遍历孩子节点并按之前的方式插入到BST中不就是可以了么?有什么难的?
这是一个思路,但是不是太好,因为使用它我们总是会有一种提心吊胆的感觉。为什么?我们现在说明一种情况。比方说,我有一棵BST。它的待删除节点是10000,左右孩子节点都有9999个节点。那么是不是就是说我们还要再把这9999 * 2个节点再插入到BST中呢?而且插入过程中还有对树的遍历。
说明上面那么太过生硬的方法之后,现在我就来说一个软一点的方法。我们先来看下面的三张图:
图-1 删除一个无子节点的节点
图-2 删除只有一个子节点的节点
图-3 删除有两个子节点的节点
从上面的三张图我们就可以看出,要删除BST中的一个节点是要分情况讨论的。在第一种情况中,没什么好说的,就是直接删除就OK。代码如下:
private void removeNodeNoChild(Node parentNode, Node removeNode) { if (parentNode.getValue() == removeNode.getValue()) { return; } else if (parentNode.getValue() < removeNode.getValue()) { parentNode.setRight(null); } else { parentNode.setLeft(null); } }在第二种方法中,我要删除节点80。不过这个时候不能直接删除,因为待删除节点有一个子节点。我们把这个子节点挂到节点80的话父节点上就可以了。代码如下:
private void removeNodeOneChild(Node parentNode, Node removeNode) { if (parentNode.getValue() == removeNode.getValue()) { return; } if (removeNode.getValue() < parentNode.getValue()) { // 父节点的左孩子 parentNode.setLeft(removeNode.getLeft() == null ? removeNode.getRight() : removeNode.getLeft()); } else { // 父节点的右孩子 parentNode.setRight(removeNode.getLeft() == null ? removeNode.getRight() : removeNode.getLeft()); } }第三种情况就复杂一些。因为我们既不能直接删除,也不能把节点30的子节点挂到节点30的父节点20上面(因为每个节点的右孩子只能有一个,而节点30有两个孩子)。
我们的做法是找到待删除节点(节点30)左孩子中最大的节点,这里我们打到了节点27。再把节点27来替换掉要删除的节点30。这样既快捷高效又保证不破坏BST的规则结构。代码如下:
private void removeNodeTwoChild(Node parentNode, Node removeNode) { if (parentNode.getValue() == removeNode.getValue()) { return; } Node maxValueNode = maxValueNode(removeNode.getLeft()); if (removeNode.getValue() < parentNode.getValue()) { // 父节点的左孩子 parentNode.setLeft(maxValueNode); } else { // 父节点的右孩子 parentNode.setRight(maxValueNode); } maxValueNode.setLeft(removeNode.getLeft()); maxValueNode.setRight(removeNode.getRight()); }
Demo源码下载:
https://github.com/William-Hai/Binary-Sort-Tree
- 数据结构:二叉搜索树(BST)的基本操作
- 二叉搜索树(BST)的基本操作
- 二叉搜索树(BST)的基本操作
- 数据结构基础5.2:二叉搜索树(BST)的基本操作(插入、查找、删除)
- <数据结构与算法>二叉搜索树(BST)的基本操作(C语言描述)
- 数据结构回顾和总结(二叉搜索树(BST)的基本操作)
- 二叉搜索树(BST,基本操作实现)
- 【数据结构】二叉搜索树(BST)
- (BST)二叉搜索树的操作(一)
- 【数据结构基础】二叉搜索(排序)树的基本操作
- 搜索二叉树(BST)的实现
- 非线性数据结构 之 二叉搜索树(BST)
- javascript数据结构7-二叉搜索树(BST)
- 数据结构13.二叉搜索树 BST
- (数据结构)二叉树的基本操作
- *BST(二叉搜索树)
- 二叉搜索树(BST)
- (BST)二叉搜索树操作(二)
- 期末总结
- Java Web开发,Struts2、Hibernate、Spring授课视频
- centos设置为中文
- 安装NFS服务,并挂载到开发板
- 看“美团点评技术团队博客”的笔记
- 数据结构:二叉搜索树(BST)的基本操作
- 冒泡排序
- Binary Tree Postorder Traversal
- LVS + keepalived + nginx + tomcat 实现主从热备 + 负载均衡
- python3.3三种简单获取网页信息的方法
- 一篇谈论Scrum的好文章
- 五步看盘法》---韩东良(完整版)
- 喝酒不骑马的Android自学日记(10)-ProgressBar&&WebView
- poj 1979 &&hdu 1312Red and Black (bfs)