0037データ構造のSetとMap

14969 ワード

チェーンテーブルと二分探索ツリーに基づいてSetを実現し,二分探索ツリーに基づいてMapを実現する.
-----------------------------集合Set--------------------------------------
Set
void add
void remove
boolean contains
int getSize()
boolean isEmpty()
 
1、二分探索木を使用してSet集合を実現する:
package set; import tree.BST; /* * コレクションに格納されている要素を比較可能にするには、E extends Comparable*/public class BSTSetextends Comparable>implements Set{BST bst=new BST<>();@Override public int getSize(){return bst.getSize();    }     @Override     public boolean isEmpty() {         return bst.isEmpty();     }     @Override     public boolean contains(E e) {         return bst.contains(e); }@Override public void add(E e){//自分が実装したBSTクラスのaddメソッドには重複要素が含まれていないため、bst.add(e)を直接呼び出すことができる.    }     @Override     public void remove(E e) {         bst.removeElement(e);     }     @Override     public String toString() {         return bst.toString();     } }
 
 
2、チェーンテーブルを使用して集合Setを実現する:
package set; import linked.LinkedList; /* * チェーンテーブル実装のSetに含まれる要素は、Comparableインタフェース**/public class LinkedListSet implements Set{private LinkedListlinkedList;public LinkedListSet(){linkedList=new LinkedList();    }     @Override     public int getSize() {         return linkedList.getSize();     }     @Override     public boolean isEmpty() {         return linkedList.isEmpty();     }     @Override     public boolean contains(E e) {         return linkedList.contains(e); }@Override public void add(E e){//チェーンテーブルに制限要素がなく重複できないため、ここで判断if(!linkedList.contains(e){//チェーンヘッダーに新しい要素を追加する必要があり、時間複雑度が最も低いlinkedList.addFirst(e);        }     }     @Override     public void remove(E e) {         linkedList.removeElement(e);     }     @Override     public String toString() {         return linkedList.toString();     } }
 
まとめ:チェーンテーブルによるSet効率は二分探索ツリーによるSetよりも遅い.なぜなら二分探索ツリーによるチェーンテーブルのadd,remove,containsはいずれもO(h)レベルであり、hは二分探索ツリーの高さであり、満二分探索ツリーではh=log 2 nがlogが2をベースnとする対数を表すため、時間複雑度もO(log 2 n)と見なすことができる.2が基数であろうと10が基数であろうと、100が基数であろうと、O(logn)と書くことができるが、最悪の形態の二分探索ツリーは分岐が1つしかない、すなわちチェーンテーブル形式の二分探索ツリーであり、時間の複雑さはO(n)となる.一方,チェーンテーブルによるSet,add(チェーンテーブルのcontainsを呼び出して判断する),remove,containsの時間的複雑度はいずれもO(n)である.
例えば、n=100万の場合、lognは20で、両者は5万倍の差があります.すなわち、lognが1秒であれば、nは14時間かかります.このように見ると、両者の差は非常に大きいようです.nが大きくなるにつれて格差はますます大きくなる.
nlognとn 2の差はlognとnの差に相当する.
lognの効率は非常に高い.
 
秩序化集合は探索ツリーに基づいて実現することが好ましく、無秩序集合はhashテーブルに基づいて実現することが好ましい(例えば、無秩序集合はチェーンテーブルに基づいて実現効率が極めて低い)
 
 
--------------------------------------マッピングMapMapMapMapMapMapMapMapMapMapMapMapMap------------------------------------
チェーンテーブルの実装:
class Node{
K key;
V value;
Node next;
}
 
二分検索ツリーの実装:
class Node{
K key;
V value;
Node left;
Node right;
}
 
Mapインタフェース定義:
int getSize()
boolean isEmpty()
Map
void add(K,V)
V remove(K)
boolean contains(K)
V get(K)
void set(K,V)
 
1、二分探索木に基づいてMapを実現する
 
package map;

public class BSTMapextends Comparable,V> implements Map {
    private class Node{
        public K key;
        public V value;
        public Node left;
        public Node right;

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

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

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

    private int size;
    private Node root;

    public BSTMap(){
        root = null;
        size = 0;
    }

    @Override
    public int getSize() {
        // rootnode == null
       
return size;
    }

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

    @Override
    public void add(K k, V v) {
        root = add(root,k,v);
    }

    //node node node
   
private Node add(Node node,K k,V v){
        if(k == null){
            return null;
        }
        //1
       
if(node == null){
            //
           
size++;
            return new Node(k,v);
        }
        //2
       
if(k.compareTo(node.key) == 0){
            //
           
return node;
        }else if(k.compareTo(node.key) < 0){
            node.left = add(node.left,k,v);
            return node;
        }else{
            node.right = add(node.right,k,v);
            return node;
        }
    }
    @Override
    public V remove(K k) {
        V v = get(k);
        root = remove(root,k);
        return v;
    }

    //
   
public Node remove(Node node,K k){
        //1
       
if(node == null){
            return null;
        }
        //2
       
if(k.compareTo(node.key) == 0){
            // null
           
if(node.right == null){
                Node leftNode = node.left;
                node.left = null;
                size--;
                return leftNode;
            }else if(node.left == null){
                // null
               
Node rightNode = node.right;
                node.right = null;
                size--;
                return rightNode;
            }else{
                //
               
// getMinremoveMinnode
               
Node rightNode = node.right;
                Node min = minumum(rightNode);
                Node newRightNode = removeMin(rightNode);
                min.left = node.left;
                min.right = newRightNode;
                node.left = node.right = null;
                return min;

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

    //
   
private Node minumum(Node node){
        //
       
if(node.left == null){
            return  node;
        }
        return minumum(node.left);
    }

    // node
   
public Node removeMin(Node node){
        //
       
if(node.left == null){
            Node rightNode = node.right;
            node.right = null;
            size--;
            return rightNode;
        }
        // node.left
       
// node.left = node.left.right
        
node.left = removeMin(node.left);
        return node;
    }

    @Override
    public V get(K k) {
        return get(root,k);
    }

    //
   
private V get(Node node,K k){
        //1
       
if(node == null || k == null){
            return null;
        }
        //2
       
if(k.compareTo(node.key) == 0){
            //
           
return node.value;
        }else if(k.compareTo(node.key) < 0){
            return get(node.left,k);
        }else{
            return get(node.right,k);
        }
    }

    @Override
    public void set(K k, V v) {
        root = set(root,k,v);
    }

    // , node node
   
public Node set(Node node,K k,V v){
        if(k == null){
            return null;
        }
        //1
        
if(node == null){
            //
           
size++;
            return new Node(k,v);
        }
        //2
       
if(k.compareTo(node.key) == 0){
            // , add add
           
node.value = v;
            return node;
        }else if(k.compareTo(node.key) < 0){
            node.left = add(node.left,k,v);
            return node;
        }else{
            node.right = add(node.right,k,v);
            return node;
        }
    }
    @Override
    public boolean contains(K k){
        return contains(root,k);
    }

    public boolean contains(Node node,K k) {
       /* if(k == null){
            return false;
        }
        //1

        if(node == null){
            return false;
        }
        //2

        if(k.compareTo(node.key) == 0){
            return true;
        }else if(k.compareTo(node.key) < 0){
            return contains(node.left,k);
        }else{
            return contains(node.right,k);
        }*/
       //
get(root,k)
      
return get(root,k) != null;
    }
}

2、BSTMap :
package map;

import java.util.HashMap;

public class Main {
public static void main(String[] args) {
Map map = new BSTMap();
System.out.println("isEmpty:" + map.isEmpty());
int[] arr = {13,6,9,2,7,3,1,8,2,6,4,5,8};
for(int i=0;i map.add(arr[i],arr[i]);
}
System.out.println("size:" + map.getSize());
System.out.println("isEmpty:" + map.isEmpty());
System.out.println("contains5:" + map.contains(5));
System.out.println("contains1:" + map.contains(5));
System.out.println("contains12:" + map.contains(12));
System.out.println("get6:" + map.get(6));
map.set(12,12);
map.set(13,14);
System.out.println("size:" + map.getSize());
System.out.println("get12:" + map.get(12));
System.out.println("get13:" + map.get(13));

}
}

, !