二叉查找树
这里基于二叉查找树建立BST类,类使用二叉树的顺序存储键值key和键值对应的数据value。键值作为结点排序的依据,查找时依据结点的键值查找。实现了查找、插入、删除以及和有序性相关的一些方法。
/**
* 基于二叉查找树的符号表
* @author XY
*
* @param <Key> 存储的键值
* @param <Value> 存储的键值对应的数据
*/
public class BST<Key extends Comparable<Key>,Value> {
class Node{//Node类是二叉查找树中的节点,二叉树中根据结点的键值确定在二叉树中位置
private Key key;
private Value value;
private Node left;
private Node right;
private int N;//以此结点为根节点的树的结点数量
public Node(Key key,Value value){
this.key=key;
this.value=value;
}
}
/*******************内部类********************/
private Node root;
private StringBuffer sb;
public Value getloop(Key key){//基于循环的查找
Node t=root;
int com;
while(t!=null){
com=key.compareTo(t.key);
if(com>0) t=t.right;
else if(com<0) t=t.left;
else {
return t.value;
}
}
return null;
}
public Value get(Key key){//基于递归的查找
return get(root, key);
}
private Value get(Node node,Key key){
if (node==null) return null;
int com=key.compareTo(node.key);
if(com<0) return get(node.left,key);
if(com>0) return get(node.right, key);
return node.value;
}
public void put(Key key,Value value){//插入
root=put(root, key, value);
}
private Node put(Node node,Key key,Value value){//注意这里有返回值,设置返回值的目的是新建的结点要建立链接
if(node==null) node=new Node(key, value);//键不存在新建结点和链接
else {
int comp=key.compareTo(node.key);
if(comp<0) node.left=put(node.left, key, value);//从左子树中查找
else if(comp>0) node.right=put(node.right, key, value);//从右子树中查找
else node.value=value;//键存在,修改键对应的数据
}
node.N=size(node.left)+size(node.right)+1;//左子树的数量加上右子树的数量加上该节点的数量
return node;
}
public int size(){//求总结点
return size(root);
}
private int size(Node node){//求以该结点为根节点的子树的大小
if(node==null) return 0;
return node.N;
}
public Key min(){//求树中的最小键
return min(root).key;
}
private Node min(Node node){
if(node.left==null) return node;
return min(node.left);
}
public Key max(){
return max(root).key;
}
private Node max(Node node){
if(node.right==null) return node;
return min(node.right);
}
public void delmin(){//删除最小键,返回值更新连接
if(root==null) return;
root=delmin(root);
}
private Node delmin(Node node){
if(node.left==null) return node.right;
node.left=delmin(node.left);
node.N=size(node.left)+size(node.right)+1;
return node;
}
public void delmax(){//删除最大键,返回值更新连接
if(root==null) return;
root=delmax(root);
}
private Node delmax(Node node){
if(node.right==null) return node.left;
node.right=delmax(node.right);
node.N=size(node.left)+size(node.right)+1;
return node;
}
public void delete(Key key){//删除键,使用了min()和delmin()
root=delete(root, key);
}
private Node delete(Node node,Key key){
if(node==null) return null;
int com=key.compareTo(node.key);
if(com<0) node.left=delete(node.left, key);
else if(com>0) node.right=delete(node.right, key);
else{//遍历找到删除键
if(node.right==null) return node.left;
if(node.left==null) return node.right;
Node t=node;//保存指针
node=min(t.right);//取该节点右子树中的最小键为新的结点,左子树中的最大值也可。
node.right=delmin(t.right);//右子树删除最小键结点
node.left=t.left;//连左子树
}
node.N=size(node.left)+size(node.right)+1;
return node;
}
public Key floor(Key key){
Node x=floor(root, key);
if(x==null) return null;
return x.key;
}
private Node floor(Node node,Key key){
if(node==null) return null;
int com=key.compareTo(node.key);
if(com<0) return floor(node.left, key);
if(com==0) return node;
Node t=floor(node.right, key);
if(t!=null) return t;
return node;
}
public Key ceiling(Key key){
Node x= ceiling(root,key);
if(x==null) return null;
return x.key;
}
private Node ceiling(Node node,Key key){
if(node==null) return null;
int com=key.compareTo(node.key);
if(com>0) return ceiling(node.right, key);
if(com==0) return node;
Node t=ceiling(node.left, key);
if(t!=null) return t;
return node;
}
public int rank(Key key){
return rank(root,key);
}
private int rank(Node node,Key key){
if(node==null) return 0;
int comp=key.compareTo(node.key);
if(comp<0) return rank(node.left, key);
if(comp>0) return size(node.left)+1+rank(node.right,key);
return size(node.left);
}
public Key select(int n){
return select(root, n);
}
private Key select(Node node,int n){
if(node==null) return null;
if(n<size(node.left)) return select(node.left, n);
if(n>size(node.left)) return select(node.right, n-size(node.left)-1);
return node.key;
}
public String keys(Key key1,Key key2){
sb=new StringBuffer();
keys(root,key1, key2);
return sb.toString();
}
private void keys(Node node,Key key1,Key key2){
if(node==null) return;
int com1=node.key.compareTo(key1);
int com2=node.key.compareTo(key2);
if(com1>=0 && com2<=0){
sb.append(node.key+" ");
keys(node.left,key1, key2);
keys(node.right,key1, key2);
}else if (com1<0) {
keys(node.right, key1, key2);
}else if(com2>0){
keys(node.left, key1, key2);
}
}
public void show(){
sb=new StringBuffer();
show(root);
System.out.println(sb.toString());
}
private void show(Node node){
if(node.left!=null) show(node.left);
sb.append(node.key+":"+node.value+" ");
if(node.right!=null) show(node.right);
}
public static void main(String[] args) {
BST<Integer, String> bst=new BST<Integer, String>();
bst.put(6, "sgt");
bst.put(1, "lm");
bst.put(3, "cn");
bst.put(4, "rn");
bst.put(5, "jh");
bst.show();
// System.out.println(bst.getloop(8));
}
}