简体   繁体   English

如何使用二叉搜索树实现Hashtable?

[英]How do I implement a Hashtable using a Binary Search Tree?

I was able to implement Hashtable using array by simply using the following data structure. 我只需使用以下数据结构即可使用数组实现Hashtable。

LinkedList<Item<K,V>> table[]
const int MAX_SIZE = 100

ie an array of linked list(hashing with chaining). 即链表列表(带链接的散列)。

Now in various books,they say we can implement a hashtable with a BST if we want ordered data. 现在在各种书籍中,他们说如果我们想要有序数据,我们可以用BST实现哈希表。 How do I incorporate both key and value in a BST. 如何在BST中包含键和值。 Although I can store both just as I store a single item of data, but the key gives an integer that acts like an index to the array after it has been to a hash function. 虽然我可以像存储单个数据项一样存储这两个数据,但是键给出了一个整数,它就像是一个散列函数之后的数组索引。 How do I use the key in BST? 如何在BST中使用密钥? I don't need any index? 我不需要任何索引?

What I can think of is that I can compare two keys using the function and then do normal insertion,deletion accordingly. 我能想到的是我可以使用该功能比较两个键,然后相应地进行正常插入和删除。

EDITS: EDITS:

Suppose I have BST from scratch 假设我从头开始有BST

class Node {
        K key;
        V value;
        Node left;
        Node right;
    }


class BinarySearchTree {
            Node root;
        }


class Hashtable {

BinarySearchTree bst;

public void Hashtable() {
bst = new BinarySearchTree();
}

//hashfunction(K key)

//get(K Key)

//put(K key,V value)

//remove(K key)

}

How do I use the key mapped to integer to implement the 如何使用映射到整数的键来实现

insert(V value) 

in BST. 在BST。

There is already an implementation of BST in java - TreeMap . 在Java - TreeMap中已经有了BST的实现。 It's a self balancing red-black tree. 这是一种自平衡的红黑树。 I guess implementing it would not be a much problem. 我想实现它不会是一个太大的问题。 For example: 例如:

public class Hashtable<T, V> implements Map<T, V> {

    private TreeMap<T, V> bst;

    public Hashtable() {
        bst= new TreeMap<T, V>();
    }

    @Override
    public void put(T element, V value) {
        bst.put(element, value);
    }

    ...

}

Since Hashtable should be implementation of Map interface, I suggest implementing java.util.Map . 由于Hashtable应该是Map接口的实现,我建议实现java.util.Map I would use a BST through composition rather than inheritance - so we can hide the API of the BST. 我会通过组合而不是继承来使用BST - 所以我们可以隐藏BST的API。 The BST can be anything - in my code example I used Java's TreeMap class. BST可以是任何东西 - 在我的代码示例中,我使用了Java的TreeMap类。

Java specific answers have already been provided but I am guessing your question is more about the design rather than language specific implementation. 已经提供了Java特定的答案,但我猜你的问题更多的是关于设计而不是语言特定的实现。

No, we do not need to calculate an index or use a hashing function. 不,我们不需要计算索引或使用散列函数。 If we store the key,value pairs in the nodes of the bst, then its just a matter of traversing the tree by comparing the keys. 如果我们在bst的节点中存储键值对,那么只需通过比较键来遍历树。 This also gives you the added advantage of no collisions since the keys are unique. 这也为您提供了无冲突的额外优势,因为密钥是唯一的。

You could use a hashing function and hash the key and then traverse the tree based on that value but this can lead to collisions if you are not careful with the hash function and then you would have to maintain some sort of chaining. 您可以使用散列函数并对密钥进行散列,然后根据该值遍历树,但如果您不小心使用散列函数,则可能会导致冲突,然后您必须保持某种链接。

Whether to use the key or the hashed value of the key depends on the size of the key. 是否使用密钥或密钥的散列值取决于密钥的大小。 If the key size is large, it makes sense to hash it to a smaller size for faster comparison. 如果密钥大小很大,则将其散列为较小的大小以便更快地进行比较是有意义的。

You don't need to implement the hash table with link list. 您不需要使用链接列表实现哈希表。 It's only the case when the collision happens instead of using chaining which takes linear time to search O(n) , you can use a balanced bst so that the search time reduces to O(log n). 只有当碰撞发生而不是使用线性时间来搜索O(n)的链接时,才能使用平衡的bst,以便搜索时间减少到O(log n)。

Here is a simple implementation of HashMap with BST as buckets. 以下是使用BST作为存储桶的HashMap的简单实现。 This basic implementation of Map shows how put() and get() works to get data from Map backed by BST buckets. Map的这个基本实现显示了put()和get()如何工作以从BST桶支持的Map获取数据。 This BST implementation is NOT balanced. 此BST实施不平衡。 Ideally for production applications, this BST should be balanced using Red-Black tree algorithm to improve seek time. 理想情况下,对于生产应用程序,应使用红黑树算法来平衡此BST,以改善搜索时间。

With buckets implemented using balanced BST compared to Linked Lists, we are able to improve Get(key) time from O(n) to O(log n). 使用平衡BST与链接列表相比实现存储桶,我们能够将Get(键)时间从O(n)提高到O(log n)。

public class HashMapWithBST {

    private Node[] nodes;
    private static final int MAX_CAPACITY = 41;

    public HashMapWithBST() {
        nodes = new Node[MAX_CAPACITY];
    }

    /**
     * If key is a non-null object then return the hash code of key modulo hash map size as value. If key is null then return 0.
     * 
     * @param key
     * @return hash
     */
    public int getHash(String key) {

        if(key == null) {
            return 0;
        }

        int hash = key.hashCode();

        hash = hash >>> 16; // Spread the higher bits

        hash = hash % MAX_CAPACITY;

        return hash;
    }

    /**
     * In case of collisions, put the new key-value pair in a BST based on key comparisons.
     * 
     * @param key
     * @param value
     */
    public void put(String key, String value) {

        int hashOfKey = getHash(key);

        final Node newNode = new Node(key, value);

        if(nodes[hashOfKey] == null) {

            nodes[hashOfKey] = newNode;
        } else {

            Node root = nodes[hashOfKey];

            try {
                addToBSTBucket(root, newNode);
            } catch(Exception e ) {
                e.printStackTrace();
            }
        }

    }

    /**
     * If a collision happens while adding a node to Hashmap, add new node to the hashed bucket represented with a BST.
     * 
     * @param root      root of BST bucket
     * @param newNode   New Node to be added in BST bucket
     */
    private void addToBSTBucket(Node root, final Node newNode) {

        if(root == null) {
            root = newNode;
            return;
        }

        Node currentNode = root;
        Node parentNode = root;

        while(true) {

            parentNode = currentNode;

            if(newNode.key.compareTo(currentNode.key) == 0) {

                // if key values are same then just overwrite the vale in same node as duplicate keys are not allowed in this map
                currentNode.value = newNode.value;
                return;

            } else if(newNode.key.compareTo(currentNode.key) < 0) {
                currentNode = currentNode.left;

                if(currentNode == null) {
                    parentNode.left = newNode;
                    return;
                }
            } else {

                currentNode = currentNode.right;

                if(currentNode == null) {
                    parentNode.right = newNode;
                    return;
                }
            } 
        }

    }

    /**
     * Get the value for a particular key. If no key found then return null.
     * 
     * @param key
     * @return value or null
     */
    public String get(String key) {

        Node node = nodes[getHash(key)];

        if(node != null) {
            return getValueFromBST(node, key);
        }

        return null;
    }

    private String getValueFromBST(Node root, String key) {

        if(key == null) {
            return null;
        }

        while(root != null) {
            if(key.equals(root.key)) {
                return root.value;
            } else if(key.compareTo(root.key) < 0) {
                root = root.left;
            } else {
                root = root.right;
            }
        }

        return null;    
    }

    private static class Node {

        private String key;
        private String value;
        private Node left;
        private Node right;

        public Node(String key, String value) {
            this.key = key;
            this.value = value;
        }

    }
}

The complete code is located here: https://github.com/prabhash1785/DataStructures/blob/d842d07e1fc3bf7e1caed72eb6b0744a719a9bc6/src/com/prabhash/java/algorithms/datastructures/HashMapWithBST.java 完整的代码位于: https//github.com/prabhash1785/DataStructures/blob/d842d07e1fc3bf7e1caed72eb6b0744a719a9bc6/src/com/prabhash/java/algorithms/datastructures/HashMapWithBST.java

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM