javascript HashTable 散列表 (分离链接法)

* Collection/LinkedList.js

/**
 * Created by Mch on 8/26/18.
 */
function Node(e) {
    this.element = e;
    this.next = null;
}

function LinkedList() {
    this.length = 0;
    this.head = null;
}

LinkedList.prototype = {
    append: function(element) {
        var node = new Node(element), current;

        if (this.head === null) {
            this.head = node;
        } else {
            current = this.head;
            while (current.next) {
                current = current.next;
            }
            current.next = node;
        }
        this.length++;
    },
    insert: function(position, element) {
        if (position <0 || position > this.length) {
            return false;
        }
        var node = new Node(element),
            current = this.head,
            previous,
            index = 0;
        if (position === 0) {
            node.next = current;
            this.head = node;
        } else {
            while (index++ < position) {
                previous = current;
                current = current.next;
            }
            node.next = current;
            previous.next = node;
        }
        this.length++;
        return true;
    },
    removeAt: function(position) {
        if (position <0 || position > this.length) {
            return null;
        }
        var current = this.head,
            previous,
            index = 0;
        if (position=== 0) {
            this.head = current.next;
        } else {
            while (index++ < position) {
                previous = current;
                current = current.next;
            }
            previous.next = current.next;
        }
        this.length--;
        return current.element;
    },
    remove: function(element) {
        var index = this.indexOf(element);
        return this.removeAt(index);
    },
    indexOf: function(element) {
        var current = this.head,
            index = -1;
        while (current) {
            if (element === current.element) {
                return index;
            }
            index++;
            current = current.next;
        }
        return -1;
    },
    isEmpty: function() {
        return this.length === 0;
    },
    size: function() {
        return this.length;
    },
    toString: function() {
        var current = this.head,
            string = '';
        while (current) {
            string += current.element + ", ";
            current = current.next;
        }
        return string;
    },
    print: function() {
        console.log(this.toString());
    },
    getHead: function() {
        return this.head;
    }
};

exports.LinkedList = LinkedList;

* Collection/HashTable.js

/**
 * Created by Mch on 8/26/18.
 */
var LinkedList = require('./LinkedList').LinkedList;

function KeyValuePair(key, value) {
    this.key = key;
    this.value = value;
}

KeyValuePair.prototype.toString = function() {
    return '['+ this.key +'-'+ this.value +']';
};

function HashTable() {
    this.table = [];
}

// 2 hash functions
var hash = {
    loselose: function(key) {
        var hash = 0;
        for (var i = 0; i < key.length; i++) {
            hash += key.charCodeAt(i);
        }
        return hash % 37;
    },
    djb2: function(key) {
        var hash = 5381;
        for (var i = 0; i < key.length; i++) {
            hash = hash * 33 + key.charCodeAt(i);
        }
        return hash % 1013;
    }
};

// pick a hash function
HashTable.hashCode = hash.loselose;

HashTable.prototype = {
    // 分离链接
    put: function(key, value) {
        var pos = HashTable.hashCode(key);
        if (this.table[pos] === undefined) {
            this.table[pos] = new LinkedList();
        }
        this.table[pos].append(new KeyValuePair(key, value));
    },
    get: function(key) {
        var pos = HashTable.hashCode(key);
        if (this.table[pos] !== undefined) {
            var current = this.table[pos].getHead();
            while (current.next) {
                if (current.element.key === key) {
                    return current.element.value;
                }
                current = current.next;
            }
            if (current.element.key === key) {
                return current.element.value;
            }
        }
        return undefined;
    },
    remove: function(key) {
        var position = HashTable.hashCode(key);

        if (this.table[position] !== undefined) {
            var current = this.table[position].getHead();
            while (current.next) {
                if (current.element.key === key) {
                    this.table[position].remove(current.element);
                    if (this.table[position].isEmpty()) {
                        this.table[position] = undefined;
                    }
                    return true;
                }
            }
            // 检查是否为第一个或最后一个元素
            if (current.element.key === key) {
                this.table[position].remove(current.element);
                if (this.table[position].isEmpty()) {
                    this.table[position] = undefined;
                }
                return true;
            }
        }
        return false;
    },
    // TODO: 线性探查

    print: function() {
        for (var i = 0; i < this.table.length; ++i) {
            if (this.table[i] !== undefined) {
                console.log(i + ": " + this.table[i]);
            }
        }
    }
};

exports.HashTable = HashTable;

* TestHashTable.js

var HashTable = require('./Collection/HashTable').HashTable;

function TestHashTable() {}

TestHashTable.main = function() {
    var hash = new HashTable();

    hash.put('Gandalf', '[email protected]');
    hash.put('John', '[email protected]');
    hash.put('Tyrion', '[email protected]');
    hash.put('Aaron', '[email protected]');
    hash.put('Donnie', '[email protected]');
    hash.put('Ana', '[email protected]');
    hash.put('Jonathan', '[email protected]');
    hash.put('Jamie', '[email protected]');
    hash.put('Sue', '[email protected]');
    hash.put('Mindy', '[email protected]');
    hash.put('Paul', '[email protected]');
    hash.put('Nathan', '[email protected]');

    hash.print();

    console.log(hash.get('Sue'));
};

TestHashTable.main();

$ node ./TestHashTable.js
5: [[email protected]], [[email protected]], [[email protected]],
10: [[email protected]],
13: [[email protected]], [[email protected]],
16: [[email protected]], [[email protected]],
19: [[email protected]],
29: [[email protected]],
32: [[email protected]], [[email protected]],
[email protected]

线性探测法:

https://blog.csdn.net/fareast_mzh/article/details/82120675

猜你喜欢

转载自blog.csdn.net/fareast_mzh/article/details/82085749