javascript实现集合Set、字典Dictionary、HashTable
集合是由一组无序且唯一(即不能重复)的项组成的。这个数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中。
function Set() { this.items = {}; } Set.prototype = { constructer: Set, has: function(value) { return value in this.items; }, add: function(value) { if (!this.has(value)) { this.items[value] = value; return true; } return false; }, remove: function(value) { if (this.has(value)) { delete this.items[value]; return true; } return false; }, clear: function() { this.items = {}; }, size: function() { return Object.keys(this.items).length; }, values: function() { return Object.keys(this.items); //values是数组 }, union: function(otherSet) { var unionSet = new Set(); var values = this.values(); for (var i = 0; i < values.length; i++) { unionSet.add(values[i]); } values = otherSet.values(); for (var i = 0; i < values.length; i++) { unionSet.add(values[i]); } return unionSet; }, intersection: function(otherSet) { var intersectionSet = new Set(); var values = this.values(); for (var i = 0; i < values.length; i++) { if (otherSet.has(values[i])) { intersectionSet.add(values[i]); } } return intersectionSet; }, difference: function(otherSet) { var differenceSet = new Set(); var values = otherSet.values(); for (var i = 0; i < values.length; i++) { if (!this.has(values[i])) { differenceSet.add(values[i]); } } return differenceSet; }, subset: function(otherSet) { if (this.size() > otherSet.size()) { return false; } else { var values = this.values(); for (var i = 0; i < values.length; i++) { if (!otherSet.has(values[i])) { return false; } } } return true; }, }
集合表示一组互不相同的元素(不重复的元素)。在字典中,存储的是[键,值] 对,其中键名是用来查询特定元素的。字典和集合很相似,集合以[值,值]的形式存储元素,字 典则是以[键,值]的形式来存储元素。字典也称作映射。
function Dictionary() { this.items = {}; } Dictionary.prototype = { constructor: Dictionary, has: function(key) { return key in this.items; }, set: function(key, value) { this.items[key] = value; }, remove: function(key) { if (this.has(key)) { delete this.items[key]; return true; } return false; }, get: function(key) { return this.has(key) ? this.items[key] : undefined; }, values: function() { var values = []; for (var key in this.items) { if (this.has(key)) { values.push(key); } } return values; }, clear: function() { this.items = {}; }, size: function() { return Object.keys(this.items).length; }, keys: function() { return Object.keys(this.items); }, getItems: function() { return this.items; } };
散列表
HashTable类,也叫HashMap类,是Dictionary类的一种散列表实现方式。散列算法的作用是尽可能快地在数据结构中找到一个值。如果使用散列函数,就知道值的具体位置,因此能够快速检索到该值。散列函数的作用是给定一个键值,然后 返回值在表中的地址。
//lose-lose散列函数 function loseloseHashCode(key) { var hash = 0; for (var i = 0; i < key.length; i++) { hash += key.charCodeAt(i); } return hash % 37; } function HashTable() { this.table = []; } HashTable.prototype = { constructor: HashTable, put: function(key, value) { var position = loseloseHashCode(key); console.log(position + '- ' + key); this.table[position] = value; }, get: function(key) { return this.table[loseloseHashCode(key)]; }, remove: function(key) { this.table[loseloseHashCode(key)] = undefined; } }; var hash = new HashTable(); hash.put('Gandalf', 'gandalf@email.com'); hash.put('John', 'johnsnow@email.com'); hash.put('Tyrion', 'tyrion@email.com'); console.log(hash.get('Gandalf')); //gandalf@email.com console.log(hash.get('Loiane')); //undefined hash.remove('Gandalf'); console.log(hash.get('Gandalf')); //undefined
分离链接:分离链接法包括为散列表的每一个位置创建一个链表并将元素存储在里面。它是解决冲突的最简单的方法,但是它在HashTable实例之外还需要额外的存储空间。
function HashTable() { this.table = []; //lose-los散列函数 function loseloseHashCode(key) { var hash = 0; for (var i = 0; i < key.length; i++) { hash += key.charCodeAt(i); } //console.log(key + " - " + (hash % 37)); return hash % 37; } function ValuePair(key, value) { this.key = key; this.value = value; this.toString = function() { return '[' + this.key + ' - ' + this.value + ']'; } } if ((typeof this.put !== 'function') && (typeof this.put !== 'string')) { HashTable.prototype.put = function(key, value) { var position = loseloseHashCode(key); if (this.table[position] === undefined) { this.table[position] = new LinkedList(); } this.table[position].append(new ValuePair(key, value)); }; HashTable.prototype.get = function(key) { var position = loseloseHashCode(key); if (this.table[position] !== undefined) { var current = this.table[position].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; } } else { return undefined; } }; HashTable.prototype.remove = function(key) { var position = loseloseHashCode(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; } current = current.next; } //检查是否是第一个或者最后一个 if (current.element.key === key) { this.table[position].remove(current.element); if (this.table[position].isEmpty()) { this.table[position] = undefined; } return true; } } return false; }; } } var hash = new HashTable(); hash.put('Gandalf', 'gandalf@email.com'); hash.put('John', 'johnsnow@email.com'); //下面两个hash值相同 hash.put('Aaron', 'huang@gmail.com'); hash.put('Tyrion', 'tyrion@email.com'); console.log(hash.get('Gandalf')); //gandalf@email.com console.log(hash.get('Loiane')); //undefined hash.remove('Gandalf'); console.log(hash.get('Gandalf')); //undefined