1. 程式人生 > >javaScript資料結構 06 HashMap

javaScript資料結構 06 HashMap

javaScript資料結構之HashMap

01 HashMap

原理是用一個散列表,分出雜湊值,再由每個位置建立一個LinkList


02 hashMap原理

我們用一個數組,來承裝鍵值對。
我們可以這樣,實現一個雜湊演算法,來計算承裝的下標。

function HashMap() {
	var _list  = [];
	/*hash演算法,用可以計算出陣列的下標*/
	function loseloseHashCode(key) {
		// 我們簡單模擬下
		return key.charCodeAt() % 100;
	};

	this.put = function
(key, value) { var position = loseloseHashCode(key); _list[position] = value; }; this.get = function(key) { var position = loseloseHashCode(key); return _list[position]; } } var h = new HashMap(); h.put('a', 'a'); h.put('b', 'b'); console.log(h.get('a'));

上面的演算法是存在問題的,因為hash演算法沒有保障hashCode的唯一性。那麼衝突就是難免的。這就是— 雜湊衝突


當然,一個好的雜湊演算法應該儘量避免雜湊衝突

解決這個問題,我們需要在陣列的位置建立一個連結串列,然後每次在連結串列裡面新增值。
如下圖所展示:

key值 hash值 連結串列
猴子1、猴子2、猴子3 0 ['孫悟空', '六耳獼猴', '通背猿猴']
5 ['豬八戒']
和尚1、和尚2 30 ['唐僧', '如來']

03 實現一個hashMap

這裡要依賴linkList

function HashMap() {
    var _table = []; 

    //裝元素的類 
    var ValuePair = function(key, value) { 
      this.key = key; 
      this.value = value;
    };

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

    /* hash演算法 */
    var loseloseHashCode = function (key) {
      var hash = 0;
      for (var i = 0; i < key.length; i++) {
        hash += key.charCodeAt(i);
      }
      return hash % 37;
    };

    this.put = function (key, value) {
      var position = loseloseHashCode(key);
      if (_table[position] == undefined) {
        _table[position] = new Linklist();
      }
      _table[position].add(new ValuePair(key, value));
    };

    this.get = function (key) {
      var position = loseloseHashCode(key);
      if (_table[position] != undefined) {
        var current = _table[position].head;
        while (current.next) {
          if (current.data.key == key) {
            return current.data.value;
          }
          current = c
          urrent.next;
        }
        if (current.data.key == key) {
          return current.data.value;
        }
      }
      return _table[loseloseHashCode(key)];
    };

    this.remove = function(key) {
      var position = loseloseHashCode(key);
      if (_table[position] != undefined) {
        var current = _table[position].head;
        var index = 0;
        while (current.next) {
          if (current.data.key == key) {
            _table[position].remove(index);
            if (_table[position].length == 0) {
              _table[position] = undefined;
            }
          }
          current = current.next;
          index++;
        }
        if (current.data.key == key) {
          _table[position].remove(index);
          if (_table[position].length == 0) {
            _table[position] = undefined;
          }
        }
      }
    }
  };
  map.put("b", "李四");
  map.remove("a");
  console.log(map.get("a"));
  console.log(map.get("b"));

04 雜湊演算法

由上可以看出:
如果沒有雜湊衝突,那麼HashMap的插入和獲取的時間複雜度基本是 O(1);
所以一個表現良好的雜湊演算法特別重要。

05 物件

寫了這麼多,我們會發現,最終居然回到了key和val的問題上。
js中,物件預設就具有如此屬性。
也就是說—js物件就是HashMap實現的。
所以,我們以後使用物件的時候就可以當做map使用。