二叉查找树与红黑树(2-3树)

二叉查找树是自上而下生长的,左子树比根节点小,右子树都比根节点大。

树的形状与插入顺序有关。

二叉树的查找、排序方法、最大键、最小键、选择操作、排名操作、删除最大键最小键

关键是通过size()函数,可以获取该节点的下的节点数。

package HardlyJava;
import java.util.*;
public class Erchashu {
	private class BST<Key extends Comparable<Key>,Value>{
		private Node root;
		private class Node{
			private Key key;
			private Value value;
			private Node left,right;
			private int N;
			public Node(Key key,Value val,int N) {
				this.key=key;
				this.value=val;
				this.N=N;
			}
		}
		public int size() {
			return size(root);
		}
		public int size(Node x) {
			if(x==null) return 0;
			else return x.N;
		}
		public Value get(Key key) {//查找键为key的对应的值
			return get(root,key);
		}
		private Value get(Node x,Key key) {//从头节点root开始,查找键为key的值
			if(x==null) return null;
			int cmp=key.compareTo(x.key);//从新定义Comparable 的compareTo函数,比较目标节点key与当前节点x.key值大小
			if(cmp<0) return get(x.left,key);
			else if(cmp>0) return get(x.right,key);
			else return x.value;
		}
		public void put(Key key,Value val) {//找到该键key,并更新该键的值为val,若没有改键则添加该节点
			root=put(root,key,val);
		}
		private Node put(Node x,Key key,Value val) {
			if(x==null) return new Node(key,val,1);
			int cmp=key.compareTo(x.key);
			if(cmp<0) x.left=put(x,key,val);
			else if(cmp>0) x.right=put(x,key,val);
			else x.value=val;
			x.N=size(x.left)+size(x.right)+1;//重新更新N值,左节点数加上右节点数加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 max(root).key;
		}
		private Node max(Node x) {
			if(x.right==null) return x;
			return max(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 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;
		}
		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);
		}
		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.left==null) return x.right;
				if(x.right==null) return x.left;
				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;
		}
		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);
		}
	}
	
}

红黑树是自下向上生长的,关键是通过左旋,右旋操作完成的。

package HardlyJava;

//import HardlyJava.Erchashu.BST.Node;

public class Redblack<Key extends Comparable<Key>,Value> {
	private static final boolean RED=true;
	private static final boolean BLACK=false;
	private Node root;
	private class Node{
		Key key;
		Value value;
		Node left,right;
		int N;
		boolean color;
		Node(Key key,Value val,int N,boolean color){
			this.key=key;
			this.value=val;
			this.N=N;
			this.color=color;
		}
	}
	private int size() {
		return size(root);
	}
	private int size(Node x) {
		if(x==null) return 0;
		else return x.N;
	}
	private boolean isRed(Node x) {
		if(x==null) return false;
		return x.color=RED;
	}
	Node rotateLeft(Node h) {
		Node x=h.right;
		h.right=x.left;
		x.left=h;
		x.color=h.color;
		h.color=RED;
		x.N=h.N;
		h.N=1+size(h.left)+size(h.right);
		return x;
	}
	Node rotateRight(Node h) {
		Node x=h.left;
		h.left=x.right;
		x.right=h;
		x.color=h.color;
		h.color=RED;
		x.N=h.N;
		h.N=1+size(h.left)+size(h.right);
		return x;
	}
	void flipColors(Node h) {
		h.color=RED;
		h.left.color=BLACK;
		h.right.color=BLACK;
	}
	//实现红黑树的插入操作
	public void put(Key key,Value val) {
		root=put(root,key,val);
		root.color=BLACK;
	}
	private Node put(Node h,Key key,Value val) {
		if(h==null) return new Node(key,val,1,RED);
		int cmp=key.compareTo(h.key);
		if(cmp<0) h.left=put(h.left,key,val);
		else if(cmp>0) h.right=put(h.right,key,val);
		else h.value=val;
		
		//关键
		if(isRed(h.right)&!isRed(h.left)) h=rotateLeft(h);
		if(isRed(h.left)&isRed(h.left)) h=rotateRight(h);
		if(isRed(h.right)&isRed(h.left)) flipColors(h);
		h.N=size(h.left)+size(h.right)+1;
		return h;
	}
	
	
	
	
	
	
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值