二叉查找树
来源:互联网 发布:spd7网络信号避雷器 编辑:程序博客网 时间:2024/05/16 04:01
首先我们来理清一个概念,在二叉树中,每个节点只能有一个父节点(根据根据点例外,它没有父节点),而且每个节点都是由左右两个链接,分别指向自己的左子节点和右子节点,我们可以将这样的链接看成一个二叉树
二叉树查找:在每次经过一次运算后,所需要的查找的数量就减少一般。随着我们不断的向下查找,当前节点所表示的子树大小也在减少(理想状态是减少一半)。当找到一个含有被查找到的键的节点(命中)或者当前子树变成空(未命中)是这个过程才会结束。
代码实现:
package com.test;import java.util.Queue;public class BST<Key extends Comparable<Key>,Value>{ /* * 二叉树的符号表 * 这段代码用二叉查找树实现了有序符号表的API,树有Node对象组成, * 每个对象都含有一对键值、两天链接和一个结点计数器N。 * 每个Node对象都是一个含有N个结点的子树的根结点 * 它的左链接指向一颗小于这个结点的所有键组成的二叉树 * 它的右结点指向一个大于这个结点的所有键促成的二叉树。 * root变量指向二叉树的根结点Node对象(这课树包含了符号表中的多有键值对) */ private Node root; //二叉查找数组的根据点 public class Node { private Key key; //键 private Value val; //值 private Node left, right; //指向子树的链接 private int N; //以该节点为根的子树中的节点总数 public Node(Key key2, Value val2, int i) { // TODO Auto-generated constructor stub } public void Node(Key key,Value val,int N) { this.key = key; this.val = val; this.N = N; } public int size() { return size(root); } private int size(Node x) { if (x == null) return 0; else return x.N; } /* * 二叉查找树的查找和排序方法的实现 */ public Value get(Key key) { return get(root,key); } private Value get(Node x , Key key){ //在以x为根据点的子树中查找并返回key所对应的值 //如果找不到则返回null if (x == null) return null; int cmp = key.compareTo(x.key); if (cmp < 0) return get(x.left,key); if (cmp >0) return get(x.right.key); else return x.val; } public void put (Key key , Value val) { //查找key,找到则更新它的值,否则为它创建一个新的结点 root = put(root , key , val); } private Node put (Node x , Key key , Value val){ //如果key存在于里x为根据点的自主中则更新它的值 //否则将以key和val为键值对的新节点插入到该子树中 if (x == null) return new Node(key , val ,1); int cmp = key.compareTo(x.key); if (cmp < 0) x.left = put(x.left,key,val); if(cmp > 0) x.right = put(x.right,key,val); else x.val = val; 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); } public Key max() { return min(root).key; } private Node max(Node x){ if (x.right == null) return x; return min(x.right); } 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 null; 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; } public Key ceiling(Key key) { Node x = ceiling(root , key); if (x == null) return null; return x.key; } private Node ceiling(Node x,Key key){ if (x == null) return null; int cmp = key.compareTo(x.key); if (cmp == 0) return x; if(cmp > 0) return floor(x.right, key); Node t = floor(x.left, key); if (t !=null ) return t; else return x; } /* * 排名(rank)和挑选(select) * rank(): * 假设我们想找到排名为k的键(即树中正好有k个小于它的键). * 如果左子树的检点数t大于k,那么我们就继续(递归)在左子树中查找排名; * 如果t等于k,我们就返回根结点中的键; * 如果t小于k,我们就(递归)在右子树中朝赵排名为(k-t-1)的键. */ public Key select(int k){ return select(root, k).key; } private Node select(Node x, int k) { //返回排名为k的节点 if(x == null) return null; int t = size(x.left); if (t > k) return select(x.left, k); else if (t< k) return select(x.right, k - t -1); else return x; } /* * rank() */ public int rank(Key key){ return rank(key , root); } private int rank(Key key,Node x) { //返回以x为根据点的自述中小于x.key的键的数量 if (x == null) return 0; int cmp = key.compareTo(x.key); if (cmp < 0) return rank(key , x.left); else if(cmp > 0) return 1 + size(x.left) + rank(key ,x.right); else return size(x.left); } /** * 删除最大键和最小键 * 二叉查找树中最难实现的一个方法就是删除键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; } public void delete(Key key) { root = delete(root, key); } 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 { if (x.right == null) return x.left; if (x.left == null) return x.right; Node t = x; x = min(t.right); x.right = deleteMin(t.right); x.left = t.left; } x.N = size(x.left) + size(x.right ) + 1; return x; } /** * 范围查找 * 要实现能够返回给定范围内键的keys()方法 * 我们首先需要一个遍历二叉查找树中的的基本方法 * 叫做中序遍历 */ public Iterable<Key> keys() { return keys(min() ,max()); } public Iterable<Key> keys(Key lo , Key hi){ Queue<Key> queue = new Queue<Key>(); keys(root, queue, lo, hi); return queue; } private void keys(Node x, Queue<Key> queue,Key lo,Key hi) { if (x == null) return; int cmplo = lo.compareTo(x.key); int cmphi = hi.compareTo(x.key); if (cmplo < 0) keys(x.left,queue,lo,hi); if(cmplo <= 0 && cmphi >= 0) queue.enqueue(x.key); if (cmphi > 0) keys(x.right, queue, lo, hi); }}}
阅读全文
0 0
- 查找--二叉查找树
- 二叉树、二叉查找树
- 二叉树 & 二叉查找树
- 【查找结构】二叉查找树
- 查找之二叉树查找
- 查找之二叉树查找
- 查找:二叉查找树总结
- 二叉树查找树...
- 二叉树查找树
- 查找--遍历二叉树
- 二叉查找树
- 二叉查找树实现
- 二叉查找树
- 动态二叉查找树
- 最优二叉查找树
- 二叉查找树
- 二叉查找树
- 平衡二叉查找树
- Linux进程间通信之共享内存
- 内存分配
- listview条目的数据都一样,肿么办
- 乘法逆元
- ELFhash
- 二叉查找树
- 通讯方式
- 找出字符串中最长数字
- 6.3
- Ubuntu用户权限管理(chown, chmod)
- AndroidManifest.xml文件详解(service)
- OpenGL学习(一)——画一个三角形
- MD5应用于数据库中密码加密
- 机器学习框架比较