Files
povtornyy-ekzamen-2-graf-s-…/src/index.js
T

83 lines
1.8 KiB
JavaScript

class Graph {
constructor() {
this.adj = new Map();
this[Graph._logSymbol] = [];
}
addNode(node) {
if (!this.adj.has(node)) {
this.adj.set(node, new Set());
}
}
addEdge(u, v) {
if (!this.adj.has(u)) this.adj.set(u, new Set());
if (!this.adj.has(v)) this.adj.set(v, new Set());
const uSet = this.adj.get(u);
const vSet = this.adj.get(v);
if (!uSet.has(v)) {
uSet.add(v);
vSet.add(u);
}
}
removeNode(node) {
if (!this.adj.has(node)) return;
for (const neighbor of this.adj.get(node)) {
this.adj.get(neighbor).delete(node);
}
this.adj.delete(node);
}
removeEdge(u, v) {
if (this.adj.has(u)) this.adj.get(u).delete(v);
if (this.adj.has(v)) this.adj.get(v).delete(u);
}
getNeighbors(node) {
return this.adj.has(node) ? Array.from(this.adj.get(node)) : [];
}
hasEdge(u, v) {
return this.adj.has(u) && this.adj.get(u).has(v);
}
getNodes() {
return Array.from(this.adj.keys());
}
getLog() {
return this[Graph._logSymbol].slice();
}
}
Graph._logSymbol = Symbol('log');
function createGraph() {
const graph = new Graph();
const handler = {
get(target, prop, receiver) {
const value = target[prop];
if (typeof value === 'function') {
// Mutating methods that should be logged
if (['addNode', 'addEdge', 'removeNode', 'removeEdge'].includes(prop)) {
return function (...args) {
const result = value.apply(target, args);
target[Graph._logSymbol].push({ method: prop, args });
return result;
};
}
// Non-mutating methods (including getLog)
return value.bind(target);
}
return value;
},
};
return new Proxy(graph, handler);
}
module.exports = { Graph, createGraph };