二分搜索树--完整版
来源:互联网 发布:矩阵的范数 编辑:程序博客网 时间:2024/06/05 06:47
1介绍
包含二分搜索树的插入,删除,遍历,等几乎全部功能 ,如果想知道什么是二分搜索树,请查看我的上一篇博客,废话少说,上代码
2 实现–完整版
import java.util.LinkedList;/** * 二分搜索树 * * @author xld * * @param <Key> * @param <Value> */public class BST<Key extends Comparable<Key>, Value> { /** * 树中的节点 设置为内部类 * * @author xld * */ private class Node { private Key key; private Value value; private Node left, right; public Node(Key key, Value value) { this.key = key; this.value = value; left = right = null; } public Node(Node node){ this.key=node.key; this.value=node.value; this.left=node.left; this.right=this.right; } } // 根节点 private Node root; // 树中的节点个数 private int count; // 构造函数 默认构造一棵空二分搜索树 public BST() { root = null; count = 0; } // 返回二分搜索树节点个数 public int size() { return count; } // 判断二分搜索树是否为空 public boolean isEmpty() { return count == 0; } // 向二分搜索树中插入一个新的(key,value)数据对 public void insert(Key key, Value value) { root = insert(root, key, value); } // 查看二分搜索树中是否包含该元素 public boolean contain(Key key, Value value) { return contain(root, key); } // 查看键值为key的元素在二分搜索树中的value public Value search(Key key) { return search(root, key); } // 二分搜索树的前序遍历 public void preOrder() { preOrder(root); } // 二分搜索树的中序遍历 public void inOrder() { inOrder(root); } // 二分搜索树的后序遍历 public void postOrder() { postOrder(root); } // 二分搜索树的层序遍历 public void levelOrder() { // 使用LinkedList 作为队列 LinkedList<Node> q = new LinkedList<Node>(); q.add(root); while (!q.isEmpty()) { Node node = q.remove(); System.out.println(node.key); if (node.left != null) q.add(node.left); if (node.right != null) q.add(node.right); } } // 寻找二分搜索树的最小的键值 public Key minimum() { assert count != 0; Node minNode = minimum(root); return minNode.key; } //寻找二分搜索树中最大的键值 public Key maximum(){ assert count!=0; Node maxNode = maximum(root); return maxNode.key; } //从二分搜索树中删除最小值所在的节点 public void removeMin(){ if(root !=null) root= removeMin(root); } //从二分搜索树中删除最大值所在节点 public void removeMax(){ if(root !=null) root = removeMax(root); } public void remove(Key key){ root = remove(root,key); } /** * 寻找key的floor值,递归算法 * 如果不存在key的floor值(key比BST的最小值还小) 返回null * @param key * @return */ public Key floor(Key key){ if(count==0 || key.compareTo(minimum())<0) return null; Node floorNode = floor(root,key); return floorNode.key; } public Key ceil(Key key){ if(count==0 || key.compareTo(maximum())>0) return null; Node ceilNode =ceil(root,key); return ceilNode.key; } // ************************** // 二分搜索树的辅助函数 // ************************** /** * 向以node为根的二分搜索树中,插入节点(key,value),使用递归算法 返回插入节点后的二分搜索树的根 * * @param node * @param key * @param value * @return */ private Node insert(Node node, Key key, Value value) { if (node == null) { count++; return new Node(key, value); } if (key.compareTo(node.key) == 0) node.value = value; else if (key.compareTo(node.key) < 0) node.left = insert(node.left, key, value); else node.right = insert(node.right, key, value); return node; } /** * 查看以node为根的二分搜索树中是否包含键值为key的节点,使用递归算法 若value不存在 则返回false * * @param node * @param key * @return */ private boolean contain(Node node, Key key) { if (node == null) return false; if (key.compareTo(node.key) == 0) return true; else if (key.compareTo(node.key) < 0) return contain(node.left, key); else return contain(node.right, key); } /** * 查看以node为根的二分搜索树中键值为key的节点的value值,使用递归算法 * * @param node * @param key * @return */ private Value search(Node node, Key key) { if (node == null) return null; if (key.compareTo(node.key) == 0) return node.value; else if (key.compareTo(node.key) < 0) return search(node.left, key); else return search(node.right, key); } /** * 二分搜索树的前序遍历 * * @param node */ private void preOrder(Node node) { if (node != null) { System.out.println(node.key); preOrder(node.left); preOrder(node.right); } } /** * 二分搜索树的中序遍历 * * @param node */ private void inOrder(Node node) { if (node != null) { inOrder(node.left); System.out.println(node.key); inOrder(node.right); } } /** * 二分搜索树的后序遍历 * * @param node */ private void postOrder(Node node) { if (node != null) { postOrder(node.left); postOrder(node.right); System.out.println(node.key); } } /** * 二分搜索树中最小的节点就是最左侧的节点 * @param node * @return */ private Node minimum(Node node){ if(node.left==null) return node; return minimum(node.left); } private Node maximum(Node node){ if(node.right==null) return node; return maximum(node.right); } /** * 删除以node为根的二分搜索树的最小值 * @param node * @return */ private Node removeMin(Node node){ //如果以node为根的二分搜索树的左子节点为空,则node为当前最小节点 if(node.left==null){ //保存下当前的node节点的node节点 Node rightNode =node.right; //将当前node 节点的指向right的指针去除 node.right=null; //二分搜索树中节点减少一个 count--; //直接将node节点的right返回顶替当前节点 return rightNode; } //将返回节点作为当前界定啊的左节点 node.left=removeMin(node.left); return node; } private Node removeMax(Node node){ if(node.right==null){ Node leftNode = node.left; node.left=null; count--; return leftNode; } node.right=removeMax(node.right); return node; } /** * 删除掉以node为根的二分搜索树中键值为key的节点,递归算法 * 返回删除节点后新的二分搜索树的根 * @param node * @param key * @return */ private Node remove(Node node ,Key key){ if(node ==null) return null; if(key.compareTo(node.key)<0){ node.left=remove(node.left,key); return node; }else if(key.compareTo(node.key)>0){ node.right=remove(node.right,key); return node; }else { //key ==node.key //待删除节点左子树为空的情况 if(node.left==null){ Node rightNode = node.right; node.right=null; count--; return rightNode; } //待删除界定啊右子树为空的情况下 if(node.right==null){ Node leftNode = node.left; node.left=null; count--; return leftNode; } //待删除节点左右子树均不为空的情况下 //找到比待删除节点大的最小节点 即待删除右自护中最小节点 用这个界定啊顶替待删除节点的位置 Node successor = new Node (minimum(node.right)); count++; successor.right= removeMin(node.right); successor.left=node.left; node.left = node.right=null; count--; return successor; } } /** * 在以node为根的二叉搜索树中,寻找key的floor值所处的节点,递归算法 * @param node * @param key * @return */ private Node floor(Node node,Key key){ if(node == null) return null; //如果node的key值和要寻找的key值相等 //则node 本身就是key的floor节点 if(node.key.compareTo(key)==0) return node; //如果node的key值比要寻找的key值大 //则要寻找的key的floor在node的左子树中 if(node.key.compareTo(key)>0) return floor(node.left,key); //如果node的key值比要寻找的key小 //则node可能是key的floor节点,也可能不是 需要从node的右子树取寻找一下 Node tempNode = floor(node.right,key); if(tempNode!=null) return tempNode; return node; } private Node ceil(Node node,Key key){ if(node == null) return null; if(node.key.compareTo(key)==0) return node; if(node.key.compareTo(key)<0) return ceil(node.right,key); Node tempNode =ceil(node.left,key); if(tempNode!=null) return tempNode; return node; }}
阅读全文
2 0
- 二分搜索树--完整版
- 最优二分搜索树
- 最优二分搜索树
- 二分搜索树
- 二分搜索树
- 二分搜索树
- 二分搜索树(一)
- 二分搜索树(二)
- BST二分搜索树
- 二分搜索树
- 二分查找法与二分搜索树
- poj2104 线段树+二分搜索
- 二分搜索树完整实现
- 二分搜索树的实现
- java实现二分搜索树
- 二分排序(搜索)树
- 二分搜索树的遍历
- 树、二叉树、二叉搜索树(完整版)
- netty
- Codeforces 742 B. Arpa’s obvious problem and Mehrdad’s terrible solution
- Python 字符串处理
- mysql查询一张表字段在另一张表中出现的次数
- 在 AndroidStudio 中如何引入 RecylerView
- 二分搜索树--完整版
- Spark日志分析项目Demo(3)--Spark入口和DataFrame
- Spring+quartz实现定时任务集群
- asp php jsp三者的简单比较
- SyntaxError:Missing parentheses in call to 'print'
- mysql的用户权限管理
- Android 自定义底部上拉控件的实现
- 河南省多校脸萌第六场
- struts或ssh使用xml校验