Javascript 创建图类 使用邻接表

* 邻接表数据结构

* 创建字典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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fareast_mzh

打赏个金币

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值