Simple learning for JS hash lists

Simple learning of JS hash lists

The HashTable class, also known as the HashMap class, is a Hash list implementation of the Dictionary class.

The purpose of the hash algorithm is to find a value in the data structure as quickly as possible.

In the previous study, if you wanted to get a value in a data structure, you had to traverse the entire data structure to find it.If you use a hash function, you know where it is and you can quickly find the value.

Using the most common hash function,'lose'hash function, simply add the ASCII code values of each letter in each key value and use the resulting hash values as addresses.

(key value) John (hash function) 74+111+104+110 (hash value) 399 forms a Hash list

address Data key-value pairs
[399] john/john@email.com
...
[685] gandalf/@email.com

Related operation methods

Create a Hash list

function HashTable() {
  var table = [];
}

Implements a hash function, which adds ASCII code values.

var loseloseHashTable = function(key) {
  var hash = 0;
  for(var i = 0; i < key.length; i++) {
    hash += key.charCodeAt(i);
  }
  return hash % 37; //This is just to get a smaller number, except for one
}

Implement the put(key, value) method to add a new item to the hash list.

this.put = function (key, value) {
  var position = loseloseHashTable(key); //Get the hash value, location
  table[position] = value;
};

Implement the get(key) method to return a specific value retrieved from the key value.

this.get = function(key) {
  var position = loseloseHashTable(key);
  return table[position];
};

Implement the remove() method to remove data values corresponding to key values from the hash.

this.remove = function(key) {
  table[loseloseHashTable(key)] = undefined; //Locations without data occupancy default to undefined
};

Specific usage method is not redundant here, that is, method call.

What about conflicts?

If more than one key has the same hash value, then the latter element will cover the former element with the same hash value.
How to solve it?

  • Separate Links

Separate Link creates a chain table for each location in the Hash list and stores the elements there.

address Chain list stores data
[5] [no1/no1.com] Pointer-> [no2/no2.com] Pointer-> [X]null

On address 5, there are two elements no1.com and no2.com on the list instance.

You need to add a valuePair class to represent the elements of the instances that will be added to the chain table.

var valuePair = function(key, value) {
  this.key = key;
  this.value = value;
  this.toString = function() {
    return `[${this.key} - ${this.value}]`;
  }
}

Override a put() method

this.put = function(key, value) {
  var position = loseloseHashTable(key);
  if(table[position] == undefined) {
    table[position] = new LinkedList(); //Initialize a LinkedList instance if this location is the first time an element has been added
  }
  table[position].append(new valuePair(key, value)); //The append method of the chain table implementation adds a valuePair instance.
};

Override a get(key) method

this.get = function(key) {
  var position = loseloseHashTable(key);
  if(table[position] !== undefined) { //Element exists in position
    //Traverse the list of chains to find keys/values
    var current = table[position].getHead();
    while (current.next) { //You can't traverse the last place in the list here
      if(current.element.key === key) {
        return current.element.value; //The element property is an instance of valuePair and contains key and value properties
      }
      current = current.next;
    }

    //Check if the element is first or last in the list
    if(current.element.key === key) {
      return current.element.value;
    }
  }
  return undefined; //No value at position
};

Override remove(key) method

this.remove = function(key) {
  var position = loseloseHashTable(key);

  if(table[position] !== undefined) {
    var current = table[position].getHead();
    while (current.next) {
      if(current.element.key === key) {
        table[position].remove(current.element); //remove Method for Chain List Implementation
        if(table[position].isEmpty()) { //Determine if the list is empty after deleting elements
          table[position] = undefined;
        }
        return true;
      }
      current = current.next;
    }

    //Check whether it is the first or last element
    if(current.element.key === key) {
      table[position].remove(current.element);
      if(table[position].isEmpty()) {
        table[position] = undefined;
      }
      return true;
    }
  }
  return false;
}
  • Linear Exploration

If the index position is already occupied, try the position of index+1, and so on.

5 is occupied, look for 6, 6 is occupied, look for 7, 7 is not occupied and assign a value (should be at position 5, but linear exploration becomes position 7)

Implement put(key, value) method

this.put = function(key, value) {
  var position = loseloseHashTable(key);
  if(table[position] === undefined) { //This position is not occupied
    table[position] = new valuePair(key, value);
  } else {
    var index = ++position; //Find Next Location
    while(table[index] !== undefined) { //Occupied Continue to Find Next Location
      index ++;
    }
    table[index] = new valuePair(key, value);
  }
};

Implement get() method

this.get = function(key) {
  var position = loseloseHashTable(key);
  if(table[position] !== undefined) {
    if(table[position].key === key) { //Example location 5
      return table[position].value; //Mark 1
    } else {
      var index = ++position;
      while(table[index] !== undefined && (table[index] && table[index].key !== key)) { //This location has elements but is not an element to look for
        index ++; //Index increase
      }
      if(table[index] && table[index].key === key) { //Confirm Correctness
        return table[index].value; //Found 7//Marker 2
      }
    }
  }
  return undefined;
};

Implement the remove() method

All you need to do is change the position codes of marks 1 and 2 of the get method
Change to table[index] = undefined;

Better hash function

var djb2HashCode = function(key) {
  var hash = 5381; //Initialize a hash variable and assign it to a prime number 5381
  for(var i = 0; i < key.length; i++) { //ergodic
    hash = hash * 33 + key.charCodeAt(i);
  }
  return hash % 1013;
}

In comparison, there will be much fewer conflicts~

Keywords: Javascript ascii

Added by mpb001 on Fri, 12 Jul 2019 19:14:35 +0300