Source: UndirectedGraph.js

import { Set } from "immutable";
import { DiGraph } from "@/DiGraph";
import { Tuple } from "@/utils";
/**
 * An unweighted undirected graph that does not allow parallel edges or self
 * loops.
 * Implemented as a Digraph with edges (v, w) and (w, v) for every edge (v, w).
 * @template V the type of the vertex id.
 * @extends DiGraph
 */
export class UndirectedGraph extends DiGraph {
    /**
     * @inheritDoc
     */
    isDirected() {
        return false;
    }
    /**
     * @inheritDoc
     */
    addEdge(v, w) {
        super.addEdge(v, w);
        super.addEdge(w, v);
    }
    /**
     * @inheritDoc
     */
    removeEdge(v, w) {
        super.removeEdge(v, w);
        super.removeEdge(w, v);
    }
    /**
     * @inheritDoc
     */
    edges() {
        // should only return edge once
        // eslint-disable-next-line new-cap
        const edges = Set().asMutable();
        for (const [v, { outVtx }] of this._adj) {
            for (const w of outVtx) {
                // eslint-disable-next-line new-cap
                edges.add(Tuple(...this.getSmallestEdge(v, w)));
            }
        }
        const edgeArray = edges.toArray();
        return edgeArray.map(edge => edge.toArray());
    }
    /**
     * Orders the edge (u', v') such that u' < v'.
     * @param {V} v the first vertex.
     * @param {V} w the second vertex.
     * @return {V[]} the ordered edge.
     * @protected
     */
    getSmallestEdge(v, w) {
        if (v < w)
            return [v, w];
        return [w, v];
    }
}