1.什么是二叉查找树
二叉查找树是应用了链表的灵活性和数组的查找的高效性来实现对数据的操作和查找。
二叉查找树要么是一棵空树,要么就必须具有如下特征:
1.二叉查找树只能有左右两棵子树
2.根节点的值大于左子树的值,小于右子树的值(左右子树不为空的情况)
3.每个节点都有相应的键和值,且不存在键值相同的点
2.二叉查找树的作用
对数据进行排序以实现对数据的高效查找。
3.二叉查找树与二分法的区别
二叉查找树是基于节点的,通过链表结构实现的,而二分法是通过数组实现的,所以当
插入数据或者删除数据的时候,二叉查找树不需要移动后面的那些节点数据,只需要改变节
点的所指的方向就可以了,而二分法是数组实现的,插入和删除数据需要将后面的数据移动
一位,因此二叉查找树比二分法更加高效。
4.二叉查找树的实现
- import java.util.Iterator;
- /**
- * 二叉查找树
- * @author spenglu
- *
- */
- public class BinarySearchTree<Key extends Comparable<Key>,Value> {
- private Node root;
- private class Node{
- private Key key;
- private Value value;
- private Node left;
- private Node right;
- private int n; //以该节点为根的子数中的节点总数
- public Node(Key key,Value value,int n){
- this.key = key;
- this.value = value;
- this.n = n;
- }
- }
- //节点总数
- public int size(){
- return size(root);
- }
- private int size(Node root2) {
- // TODO Auto-generated method stub
- if (root2==null) return 0;
- return root2.n;
- }
- //通过键获取相应的值
- public Value get(Key key){
- return get(root,key);
- }
- private Value get (Node root2, Key key) {
- // TODO Auto-generated method stub
- if (root2==null) return null;
- int cmp = key.compareTo(root2.key);
- if (cmp<0) return get(root2.left, key);
- if (cmp>0) return get(root.right, key);
- else return root2.value;
- }
- //插入相应的键值对
- //如果是已存在这个节点则更新这个节点,否则插入这个新节点
- //实际就是构建二叉查找树的方法
- public void put (Key key,Value value) {
- root = put(root, key,value);
- }
- private Node put(Node root2, Key key, Value value) {
- // TODO Auto-generated method stub
- if(root2==null) return new Node(key, value, 1);
- int cmp = key.compareTo(root2.key);
- if(cmp<0) root2.left = put(root2.left, key, value);
- if(cmp>0) root2.right = put(root2.right, key, value);
- else root2.value=value;
- root2.n = size(root2.left)+size(root2.right)+1;
- return root2;
- }
- //获取值最大的键
- public Key max(){
- return max(root).key;
- }
- private Node max(Node root2) {
- // TODO Auto-generated method stub
- if(root2==null) return root2;
- return max(root2.right);
- }
- //获取值最小的键
- public Key min(){
- return min(root).key;
- }
- private Node min(Node root2) {
- // TODO Auto-generated method stub
- if(root2==null) return root2;
- return min(root2.left);
- }
- //向下取整,获取小于等于某个值的键
- public Key floor(Key key){
- Node x = floor(root,key);
- if(x==null) return null;
- return x.key;
- }
- private Node floor(Node root2, Key key) {
- // TODO Auto-generated method stub
- if(root2==null) return null;
- int cmp = key.compareTo(root2.key);
- if(cmp==0) return root2;
- if(cmp<0) return floor(root.left, key);
- Node x = floor(root2.right, key);
- if(x!=null) return x;
- else return root2;
- }
- //向上去整,获取大于等于某个值的键
- public Key ceiling(Key key){
- Node x = ceiling(root,key);
- if(x==null) return null;
- return x.key;
- }
- private Node ceiling(Node root2, Key key) {
- // TODO Auto-generated method stub
- if(root2==null) return null;
- int cmp = key.compareTo(root2.key);
- if(cmp==0) return root2;
- if(cmp>0) return ceiling(root2.right, key);
- Node x = ceiling(root2.left, key);
- if(x!=null) return x;
- else return root2;
- }
- //找到排名为k的键
- public Key select(int k){
- return select(root,k).key;
- }
- private Node select(Node root2, int k) {
- // TODO Auto-generated method stub
- if(root2==null) return null;
- int temp = size(root2);
- if(k>temp) return select(root2.right, k-temp-1);
- else if(k<temp) return select(root2.left, k);
- else return root2;
- }
- //返回给定键的排名
- public int rank(Key key){
- return rank(root,key);
- }
- private int rank(Node root2, Key key) {
- // TODO Auto-generated method stub
- if(root2==null) return 0;
- int cmp = key.compareTo(root2.key);
- if(cmp<0) return rank(root2.left, key);
- else if(cmp>0) return size(root2.left)+1+rank(root2.right,key);
- else return size(root2.left);
- }
- //删除最小值
- public void deleteMin(){
- root = deleteMin(root);
- }
- private Node deleteMin(Node root2) {
- // TODO Auto-generated method stub
- if(root2.left==null) return root2.right;
- root2.left = deleteMin(root2.left);
- root2.n = size(root2.left)+size(root2.right)+1;
- return root2;
- }
- //删除最大值
- public void deleteMax(){
- root = deleteMax(root);
- }
- private Node deleteMax(Node root2) {
- // TODO Auto-generated method stub
- if(root2.right==null) return root2.left;
- root2.right = deleteMax(root2.right);
- root2.n = size(root2.left)+size(root2.right)+1;
- return root2;
- }
- //删除给定某个给定键的值
- public void delete(Key key){
- root = delete(root,key);
- }
- private Node delete(Node root2, Key key) {
- // TODO Auto-generated method stub
- if(root2==null) return null;
- int cmp = key.compareTo(root2.key);
- if(cmp<0) root2.left = delete(root2.left, key);
- else if(cmp>0) root2.right = delete(root2.right, key);
- else{
- if(root2.right==null) return root2.left;
- if(root2.left==null) return root2.right;
- Node x = root2;
- root2 = min(x.right);
- root2.right = deleteMin(x.right);
- root2.left = x.left;
- }
- root2.n = size(root2.left)+size(root2.right)+1;
- return root2;
- }
- //二叉查找树的构建
- public void buildTree(Key key,Value value){
- root = buildTree(root, key,value);
- }
- private Node buildTree(Node root2, Key key, Value value) {
- // TODO Auto-generated method stub
- if (root2==null) return new Node(key, value, 1);
- int cmp = key.compareTo(root2.key);
- if (cmp<0) root2.left = buildTree(root2.left, key, value);
- else if (cmp>0) root2.right = buildTree(root2.right, key, value);
- else root2.value=value;
- root2.n = size(root2.left)+size(root2.right)+1;
- return root2;
- }
- public static void main(String[] args) {
- }
- }