算法笔记10:二叉查找树

二叉查找树


这里基于二叉查找树建立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));
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值