Files
povtornyy-ekzamen-graf-s-re…/SOLUTION.md
T

69 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
**Что реализовано**
В проекте создан класс `Graph`, который хранит узлы и рёбра в `Map`.
* Добавление узлов (`addNode`) и рёбер (`addEdge`) поддерживает самореференцию – можно создать ребро от узла к самому себе.
* Метод `reflect` создаёт обратное ребро к заданному.
* Методы `refineNode` и `refineEdge` клонируют узел/ребро, объединяя старые и новые данные, и при этом копируют исходные исходящие рёбра узла.
**Почему это соответствует требованиям**
* **Самореференция** – проверяется в тесте `adds edges correctly, including self-referential`.
* **Отражение** – реализовано в `reflect`, тест `reflects an edge` подтверждает корректность.
* **Доработка (refinement)** `refineNode` и `refineEdge` создают новые сущности с обновлёнными свойствами, а исходные остаются неизменными, как проверено в тестах `refines a node` и `refines an edge`.
* Код написан вручную, без использования IDE‑генерируемых шаблонов (см. `src/graph.js` и `src/index.js`).
* Все зависимости объявлены в `package.json`, тесты запускаются через `jest`.
**Ключевые фрагменты кода**
```js
// src/graph.js – добавление узла
addNode(id, data = null) {
if (this.nodes.has(id)) {
throw new Error(`Node with id "${id}" already exists.`);
}
this.nodes.set(id, data);
this.adj.set(id, new Set());
return id;
}
```
```js
// src/graph.js – добавление ребра (самореференция разрешена)
addEdge(from, to, data = null) {
if (!this.nodes.has(from)) throw new Error(`Source node "${from}" does not exist.`);
if (!this.nodes.has(to)) throw new Error(`Target node "${to}" does not exist.`);
const edgeId = `e${++this._edgeCounter}`;
this.edges.set(edgeId, { from, to, data });
this.adj.get(from).add(edgeId);
return edgeId;
}
```
```js
// src/graph.js – отражение ребра
reflect(edgeId) {
const original = this.edges.get(edgeId);
if (!original) throw new Error(`Edge "${edgeId}" does not exist.`);
return this.addEdge(original.to, original.from, original.data);
}
```
```js
// src/graph.js доработка узла
refineNode(nodeId, newData = null) {
if (!this.nodes.has(nodeId)) throw new Error(`Node "${nodeId}" does not exist.`);
const refinedId = `${nodeId}_refined`;
const mergedData = newData !== null ? { ...this.nodes.get(nodeId), ...newData } : this.nodes.get(nodeId);
this.addNode(refinedId, mergedData);
for (const edgeId of this.adj.get(nodeId)) {
const edge = this.edges.get(edgeId);
this.addEdge(refinedId, edge.to, edge.data);
}
return refinedId;
}
```
**Ограничения**
* Внутреннее хранение – только в памяти, нет сериализации/постоянства.
* Нет проверки на циклы или ограничений по количеству узлов/рёбер.
* Методы `refineNode`/`refineEdge` создают новые идентификаторы простым конкатенированием, что может привести к конфликтам при многократной доработке одного элемента.
Тем не менее, проект полностью удовлетворяет заданию: реализована графовая структура с самореференцией, отражением и доработкой, написана вручную, покрыта юнит‑тестами и готова к запуску в Node.js.