* 邻接表数据结构
* 创建字典Dictionary或HashMap数据结构 存储邻接表 Collection/Dictionary.js
/**
* Created by Mch on 8/20/18.
*/
function Dictionary() {
this.map = [];
}
function KeyValuePair(key, value) {
this.key = key;
this.value = value;
}
KeyValuePair.prototype.toString = function() {
return '['+ this.key +'-'+ this.value +']';
};
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
Dictionary.hashCode = hash.djb2;
Dictionary.prototype.has = function(key) {
return !(this._get(key) === undefined);
};
Dictionary.prototype.set = function(key, value) {
// this.items[key] = value;
var position = Dictionary.hashCode(key);
if (this.map[position] === undefined) {
this.map[position] = new KeyValuePair(key, value);
} else {
var index = ++position;
while (this.map[index] !== undefined) {
index++;
// Array index out of bounds! realloc
if (index >= this.map.length) {
var a = new Array(this.map.length*2);
console.debug("realloc - " + a.length);
this.map.forEach(function(e, i) {
a[i] = e;
});
delete this.map;
this.map = a;
}
}
this.map[index] = new KeyValuePair(key, value);
}
};
/**
* get
* @param key
* @returns KeyValuePair
* @private
*/
Dictionary.prototype._get = function (key) {
var position = Dictionary.hashCode(key);
if (this.map[position] !== undefined) {
if (this.map[position].key === key) {
return this.map[position];
} else {
var index = ++position;
while (index < this.map.length &&
(this.map[index] === undefined || this.map[index].key !== key))
{
index++;
}
if (index >= this.map.length || this.map[index] === undefined) {
return undefined;
}
if (this.map[index].key === key) {
return this.map[index];
}
}
}
return undefined;
};
Dictionary.prototype.get = function(key) {
var kv = this._get(key);
if (kv !== undefined && kv instanceof KeyValuePair) {
return kv.value;
}
return undefined;
};
Dictionary.prototype.remove = function(key) {
var position = Dictionary.hashCode(key);
if (this.map[position] === undefined) {
return false;
}
if (this.map[position].key === key) {
this.map[position] = undefined;
} else {
var index = ++position;
while (this.map[index] === undefined ||
this.map[index].key !== key) {
index++;
}
if (this.map[index].key === key) {
this.map[index] = undefined;
}
}
return true;
};
Dictionary.prototype.keys = function() {
return this.map.reduce(function(a, c) {
if (c.key !== undefined) {
a = a.push(c.key);
}
return a;
}, []);
};
Dictionary.prototype.values = function() {
return this.map.reduce(function(a, c) {
if (c.key !== undefined) {
a = a.push(c.value);
}
return a;
}, []);
};
Dictionary.prototype.getItems = function() {
return this.map.reduce(function(o, c) {
if (c.key !== undefined) {
o[c.key] = c.value;
}
return o;
}, {});
};
Dictionary.prototype.clear = function() {
this.map = this.map.map(function (kv) {
if (kv !== undefined) {
kv = undefined;
}
return kv;
});
this.map = [];
};
Dictionary.prototype.size = function() {
return this.map.reduce(function(a, c) {
if (c.key !== undefined) {
a++;
}
return a;
}, 0);
};
Dictionary.prototype.print =function() {
for (var i = 0; i < this.map.length; ++i) {
if (this.map[i] !== undefined) {
console.log(i + ": " + this.map[i]);
}
}
};
exports.Dictionary = Dictionary;
* 创建图类 Collection/Graph.js
/**
* Created by Mch on 9/2/18.
*/
var Dictionary = require('./Dictionary').Dictionary;
function Graph() {
this.vertices = [];
// 邻接表由图中每个顶点的相邻顶 点列表所组成。
this.adjList = new Dictionary();
}
Graph.prototype = {
addVertex: function(v) {
this.vertices.push(v);
this.adjList.set(v, []);
},
addEdge: function(v, w) {
// 无向图
this.adjList.get(v).push(w);
this.adjList.get(w).push(v);
},
toString: function() {
// this.adjList.print();
var s = '';
for (var i = 0; i < this.vertices.length; i++) {
s += this.vertices[i] + ' -> ';
var neighbors = this.adjList.get(this.vertices[i]);
for (var j = 0; j < neighbors.length; j++) {
s += neighbors[j] + ' ';
}
s += '\n';
}
return s;
}
};
exports.Graph = Graph;
* TestGraph.js
/**
* Created by Mch on 9/2/18.
*/
var Graph = require('./Collection/Graph').Graph;
var graph = new Graph(),
myVertices = ['A','B','C','D','E','F','G','H','I'];
myVertices.forEach(function(v) {
graph.addVertex(v);
});
graph.addEdge('A', 'B'); //{9}
graph.addEdge('A', 'C');
graph.addEdge('A', 'D');
graph.addEdge('C', 'D');
graph.addEdge('C', 'G');
graph.addEdge('D', 'G');
graph.addEdge('D', 'H');
graph.addEdge('B', 'E');
graph.addEdge('B', 'F');
graph.addEdge('E', 'I');
console.log(graph.toString());
A -> B C D
B -> A E F
C -> A D G
D -> A C G H
E -> B I
F -> B
G -> C D
H -> D
I -> E