JAVA數據結構之BSTMap

BSTMap

  • 由BST底層實現的映射

接口

public interface Map<K,V> {
    void add(K key, V value);
    V remove(K key);
    boolean contains(K key);
    V get(K key);
    void set(K key,V newValue);
    int getSize();
    boolean isEmpty();
}

代碼實現

public class BSTMap<K extends Comparable<k>,V>implements Map<k,v>{

    //定義節點類型
    private class Node{
        public K key;
        public V value;
        public Node left,right;

        public Node(K key,V value){
            this.key = key;
            this.value = value;
            right = null;
            left = null;
        }
    }

    //定義BSTMap的成員變量 根結點,
    private Node root ;
    private int size;

    //構造函數
    public BSTMap(){
        root = null;
        size = 0;
    }

    @Override 
    public int getSize(){
        return size;
    }

    @Override
    public boolean isEmpty(){
        return size == 0;
    }

    //向該BST中插入鍵值對
    @Override
    public void add(K key, V value){
        root = add(root,key,value);
    }

    private Node add(Node node, K key, V value){
        //判斷傳入結點是否爲空(葉子結點)
        if(node == null){
            size++;
            return new Node(key,value);
        }
        //不爲空,則判斷插入節點位置
        if(key.compareTo(node.key)==0){
            //直接返回
            return node;
        }else if(key.compareTo(node.key)<0){
            return node.left;
        }else{
            return node.right;
        }
    }

    private Node getNode(Node node,K key){
        if(node==null) return null;

        if(key.compareTo(node.key)==0){
            return node;
        }else if(key.compareTo(node.key)<0){
            return node.left;
        }else{
            return node.right;
        }

    }

    @Override
    public boolean contains(K key){
        return getNode(root,key)!=null;
    }

    @Override
    public V get(K key){
        Node node = getNode(root,key);
        return node == null?nul:node.value;
    }

    @Override
    public void set(K key, V newValue){
        Node node = getNode(root,key);
        if(node == null){
            throw new IllegalArgumentException(key+ " doesn't exist");
        }
        node.value = newValue;
    }

    //重點:分三種情況討論
    //刪除節點的左右子樹 是否爲空討論
    //1.左子樹爲空
    //2.右子樹爲空
    //3.都不爲空【難點】
    @Override
    public V remove(K key){
        Node node = getNode(root,key);
        if(Node != null){
            root = remove(root,key);
            return node.value;
        }
        return null;
    }

    // 刪除以node爲根的二分搜索樹中值爲e的節點,遞歸算法
    // 返回刪除節點後新的二分搜索樹
    private Node remove(Node node, K key) {
      if(node == null){
          return null;
      }
      if(key.compateTo(node.key) < 0){
          node.left = remove(node.left,key);
          return node;
      }else if(key.compareTo(node.key) > 0){
          node.right = remove(node.right,key);
          return node;
      }else{//=0 刪除元素
      //如果左子樹爲空,右子樹節點替換該節點
          if(node.left == null){
              Node rightNode = node.right;
              node.right = null;
              size--;
              return rightNode;
          }
      //如果右子樹爲空,右子樹節點替換該節點
          if(node.right == null){
              Node leftNode = node.left;
              node.left = null;
              size--;
              return leftNode;
          }

        //後繼節點替代刪除節點 ;還有前驅節點刪除節點
        //刪除節點,左右子樹均不爲空的情況
        //找到比待刪除節點大的最小節點,即待刪除節點右子樹的最小節點
        //用這個節點頂替待刪除的節點位置
        Node successor = minimun(node.right);
        successor.right = removeMin(node.right);//返回的最小節點的根
        success.left = node.left;
        node.right = node.left = null;
        return successor;
      }
    }

    private Node minimum(Node node){
        if(node.left == null){
            return node;
        }else{
            return minimum(node.left);
        }
    }

    // 刪除以node爲根的二分搜索樹中的最小節點
    // 返回刪除節點後新的二分搜索樹的根
    private Node removeMin(Node node){
        // 如果爲空 刪除node
        if(node.left == null){
            Node rightNode = node.right;
            node.right = null;
            size--;
            return rightNode;
        }
        //如果不爲空,繼續遞歸
        node.left = removeMin(node.left);
        //在刪除完之後,沒有影響的子樹,直接返回
        return node;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章