算法-树(1)—BST(二叉搜索树)
来源:互联网 发布:ipv6 无网络访问权限 编辑:程序博客网 时间:2024/06/07 15:00
本文基于BST结构主要实现查找,删除功能
此种数据结构较为简单,主要分析添加查找删除功能
后附完整代码
1.BST定义:
1).每个结点均有键值对,其中键值实现排序;
2).每个结点的都大于它的左结点,小于它的右结点。
2. 主要实现(递归)
结点内部类Node:`private class Node{ private Key key; private Value value; private Node left ,right; private int N; public Node(Key key,Value value,int N) { this.key = key; this.value = value; this.N = N; }}`
1).添加put
思想:键值不能相同的原则,所以先递归查找是否存在这样的键值,若存在,则更新value值,否则添加相应的键值对到对应的位置。
实现:
private Node put(Node x,Key key,Value value) { if(x == null) return new Node(key,value,1); int cmp = key.compareTo(x.key); if (cmp<0) x.left = put(x.left,key,value); else if (cmp>0) x.right = put(x.right,key,value); else x.value = value; x.N = size(x.left)+size(x.right)+1; return x; }
2).删除deleteMin,delete
1.删除最小值:
查找最小值:递归查找左子树,若左子树为null,则递归右子树,查找Node.left==null的结点,次结点即为树的最小值。
删除最小值:删除最小值后,最小结点的右子树,接到最小值父结点的左子树中。
private Node deleteMin(Node x) { if(x.left == null) //此处返回需要删除的最小结点的右子树(这样才能保证后面结点不丢失). return x.right; //递归到最小结点时,返回了x.right,此处令最小结点的父结点的左子树等于返回的x.right. //而需要删除的结点,被当成垃圾系统回收. x.left = deleteMin(x.left); //更新计数器. x.N = size(x.left)+size(x.right)+1; return x; }
2.删除任意结点(传入键值):
思想:首先肯定先递归查找的删除的键值(假设x结点),删除结点x时,我们需要使用到deleteMin,找到以x为父结点的子树的,用于替换x位置的结点。
private Node delete(Node x,Key key) { if(x == null) return null; int cmp = key.compareTo(x.key); if(cmp < 0) x.left = delete(x.left,key); else if(cmp > 0) x.right = delete(x.right,key); else { //此处x为需要删除的结点.判断x是否为单结点,若为单结点,返回x.left或者x.right即能删除x结点. if(x.right == null) return x.left; if(x.left == null) return x.right; //若不为单结点.创建t结点,保存x的左右连接状态,再查找x右子树的最小结点(此结点即为新的取代x结点的结点). Node tmp = x; x = min(tmp.right); x.right = deleteMin(tmp.right); x.left = tmp.left; } x.N = size(x.left)+size(x.right)+1; return x; }
3.性能分析:
二分查找法(有序数组):
最坏:查找—lgN。插入—N
平均:查找—lgN。插入—N/2
二叉查找树:
最坏:查找—N。插入—N
平均:查找—1.39lgN。插入—1.39lgN
BST的性能与树的高度成正比。
3. 完整代码
package search;/** * @author : 罗正 * @date time:2016年9月7日 下午9:47:08 **/public class BSTsearch <Key extends Comparable<Key> ,Value>{ private Node root; /** * 内部类:树结点——Node * @param args */ private class Node { private Key key; private Value value; private Node left ,right; private int N; public Node(Key key,Value value,int N) { this.key = key; this.value = value; this.N = N; } } public int size(){ return size(root); } private int size(Node x) { if (x == null) return 0; else return x.N; } /** * funtion:根据传入的key值,递归查找二叉树,无则返回null. * @param key * @return */ public Value get (Key key) { return get(root,key); } private Value get(Node x,Key key) { if(x == null) return null; int cmp = key.compareTo(x.key); if (cmp<0) return get(x.left,key); else if (cmp>0) return get(x.right,key); else return x.value; } /** * 查找key值,找到则更新,没有则添加. * @param key * @param value */ public void put(Key key,Value value) { root = put(root,key,value); } /** * 没有则插入root的子树当中 * @param x * @param key * @param value * @return */ private Node put(Node x,Key key,Value value) { if(x == null) return new Node(key,value,1); int cmp = key.compareTo(x.key); if (cmp<0) x.left = put(x.left,key,value); else if (cmp>0) x.right = put(x.right,key,value); else x.value = value; x.N = size(x.left)+size(x.right)+1; return x; } public Key min() { return min(root).key; } private Node min(Node x) { if(x.left == null) return x; return min(x.left); } /** * 返回小于等于key的最大键. * @param key * @return */ public Key floor(Key key) { Node x = floor(root,key); if(x == null) return null; return x.key; } private Node floor(Node x,Key key) { if( x == null) return x; int cmp = key.compareTo(x.key); if(cmp == 0) return x; if(cmp<0) return floor(x.left,key); Node t = floor(x.right,key); if(t != null) return t; else return x; } /** * 根据传入的int k值,查找在树中的key值,并返回 * @param k * @return */ public Key select(int k) { return select(root,k).key; } private Node select(Node x,int k) { if(x == null) return null; int num = size(x.left); if(num > k) return select(x.left,k); else if(num < k) return select(x.right,k-num-1); else return x; } /** * 根据传入的key,查找在树中的rank. * @param key * @return */ public int rank(Key key) { return rank(root,key); } private int rank(Node x,Key key) { if( x == null) return 0; int cmp = key.compareTo(x.key); if(cmp > 0) //此处不要忘了加上1+size(x.left) return 1+size(x.left)+rank(x.right,key); if(cmp < 0) return rank(x.left,key); else return size(x.left); } /** * 以下为较难实现的BST删除操作. * 实现步骤如下: * 1.保存要删除的结点链接.(如删除A,保存t = B.left). * 2.A指向X = min(A.left).<这个结点就是删A后,取代A位置的结点!> * 3.X取代A的操作,以及X位置抽取后,树变动的操作 * * deletemMin(). * delete(). */ public void deleteMin() { root = deleteMin(root); } private Node deleteMin(Node x) { if(x.left == null) return x.right; x.left = deleteMin(x.left); x.N = size(x.left)+size(x.right)+1; return x; } /** * 删除给定的键值对key. * @param key */ public void delete(Key key) { root = delete(root,key); } /** * 递归删除key, * 返回Node值,便于实现递归而不丢失链接. * @param x * @param key * @return */ private Node delete(Node x,Key key) { if(x == null) return null; int cmp = key.compareTo(x.key); if(cmp < 0) x.left = delete(x.left,key); else if(cmp > 0) x.right = delete(x.right,key); else { //此处x为需要删除的结点.判断x是否为单结点,若为单结点,返回x.left或者x.right即能删除x结点. if(x.right == null) return x.left; if(x.left == null) return x.right; //若不为单结点.创建t结点,保存x的左右连接状态,再查找x右子树的最小结点(此结点即为新的取代x结点的结点). Node tmp = x; x = min(tmp.right); x.right = deleteMin(tmp.right); x.left = tmp.left; } x.N = size(x.left)+size(x.right)+1; return x; } public static void main(String[] args) { // TODO Auto-generated method stub BSTsearch bst = new BSTsearch<>(); bst.put("B", "b"); bst.put("A", "a"); bst.put("D", "d"); bst.put("W", "w"); bst.put("X", "x"); bst.put("Z", "z"); System.out.println(bst.select(0)); System.out.println("rank A:"+bst.rank("A")); System.out.println("bst size :"+bst.size()); System.out.println("floor:"+bst.floor("Z")); System.out.println("min :"+bst.min()); bst.deleteMin(); System.out.println("min (mid):"+bst.min()); bst.delete("B"); System.out.println("min :"+bst.min()); System.out.println("bst size:"+bst.size()); }}
算法第四版—二叉查找树
0 0
- 算法-树(1)—BST(二叉搜索树)
- 图解:二叉搜索树算法(BST)
- *BST(二叉搜索树)
- 二叉搜索树(BST)
- 算法导论—二叉搜索树(BST)
- Java实现 二叉搜索树算法(BST)
- Java实现 二叉搜索树算法(BST)
- Java实现 二叉搜索树算法(BST)
- 算法笔记:二叉搜索树BST(未完待续)
- 二叉搜索树(BST)demo
- C++ BST(二叉搜索树)
- POJ 2309 BST(二叉搜索树)
- 二叉搜索树(BST)模板
- DSOJ BST(二叉搜索树)
- 深入理解二叉搜索树(BST)
- 搜索二叉树(BST)的实现
- 学习笔记 二叉搜索树(BST)
- 【数据结构】二叉搜索树(BST)
- vollery框架使用及支持https
- Bmob 初始化 程序停止运行解决方法
- linux设备驱动模型 之driver(驱动)原理与实例分析
- 专访吕毅:链家网技术架构的演进之路
- zookeeper学习资料
- 算法-树(1)—BST(二叉搜索树)
- 14 fragment传值
- 真分数转埃及分数的和 (贪心)
- Eclipse运行不了的常见问题及解决方案
- matplotlib.pyplot入门
- 【编程素质】MVC和三层架构
- 图像校正—透视变换
- Object-C学习笔记:解构Hello Object-C程序
- 求解汉诺塔问题