Algorithm Search⌘K

Proofs: Adjacency list

These are the human proofs of Adjacency list, at full length.

The operations of an adjacency list keep the invariant and store the edge set of the graph type full

This proof shows: correctness, termination.

Write EE for the edge set that the graph type prescribes after a sequence of operations: it starts empty, add-edge adds the edge of uu and vv, and remove-edge removes it if it is there. The edge of uu and vv is (u,v)(u, v) for a directed graph and {u,v}\{u, v\} with u≠vu \ne v for an undirected graph. The lists stand for the set E(Adj)E(\mathit{Adj}) of the edges (u,v)(u, v), or {u,v}\{u, v\}, with v∈Adj[u]v \in \mathit{Adj}[u]. The invariant (L) is (L1), no list holds a vertex twice, and (L2), for an undirected graph v∈Adj[u]  ⟺  u∈Adj[v]v \in \mathit{Adj}[u] \iff u \in \mathit{Adj}[v] and no list Adj[u]\mathit{Adj}[u] holds uu.

Lemma 1 (DELETE). Let LL be a list with no repeated entry. DELETE(L,x)(L, x) stops, and afterwards LL holds exactly the entries it held before, less xx, with no repeated entry.

Proof. Line L6 scans the finitely many indices of LL, so it stops. If no entry is xx, the list is unchanged. Otherwise let ii be the index found and ℓ\ell the last index. Line L7 writes the entry L[ℓ]L[\ell] at index ii, and line L8 removes index ℓ\ell. If i=ℓi = \ell, the net effect is to remove L[ℓ]=xL[\ell] = x. If i<ℓi < \ell, the entry at index ii, which was xx, is now L[ℓ]L[\ell], and index ℓ\ell is gone, so the entries of LL are the old ones less one copy of xx. By (L1) that was the only copy of xx, so xx is no longer in LL, and since no new value entered LL, no entry is repeated. □\square

Theorem. Assume that before an operation (L) holds and E(Adj)=EE(\mathit{Adj}) = E, and that ADD-EDGE is called only on an edge not in EE. Then after the operation (L) holds, E(Adj)E(\mathit{Adj}) equals the new EE, the queries return the answers of the graph type for EE, and the operation stops.

Proof. We take the operations in turn.

NEW (line L1). All lists are empty, so E(Adj)=∅=EE(\mathit{Adj}) = \emptyset = E, and (L) holds trivially.

ADD-EDGE (lines L2 and L3). The edge is not in E=E(Adj)E = E(\mathit{Adj}), so v∉Adj[u]v \notin \mathit{Adj}[u], and, for an undirected graph, u∉Adj[v]u \notin \mathit{Adj}[v] by (L2). Line L2 appends vv to Adj[u]\mathit{Adj}[u] and, for an undirected graph, line L3 appends uu to Adj[v]\mathit{Adj}[v]. No list gets a repeated entry, so (L1) holds. In the undirected case the two new entries are a matching pair, and u≠vu \ne v, so (L2) holds. The new entries stand for the new edge only, so E(Adj)=E∪{e}E(\mathit{Adj}) = E \cup \{e\}.

REMOVE-EDGE (lines L4 and L5). By Lemma 1, line L4 removes vv from Adj[u]\mathit{Adj}[u] and nothing else. In the undirected case line L5 removes uu from Adj[v]\mathit{Adj}[v]; the pair of entries goes away together, so (L2) holds. If the edge was absent, by (L2) neither entry is there and nothing changes. In each case E(Adj)=E∖{e}E(\mathit{Adj}) = E \setminus \{e\}, and (L1) holds by Lemma 1.

ADJACENT (line L9). It returns true exactly when v∈Adj[u]v \in \mathit{Adj}[u], that is, when the edge of uu and vv is in E(Adj)=EE(\mathit{Adj}) = E. For an undirected graph this does not depend on the order of uu and vv, by (L2).

NEIGHBORS and DEGREE (lines L10 and L11). The neighbours of uu in EE, or its out-neighbours, are exactly the entries of Adj[u]\mathit{Adj}[u]. Line L10 outputs each entry once, so by (L1) each neighbour once. Line L11 returns the length of the list, which by (L1) is the number of distinct neighbours, the degree. The loop of line L10 runs over a finite list, so it stops.

ADD-VERTEX (lines L12 and L13). The new list is empty, so the new vertex has no edges, the old lists are unchanged, and (L) holds.

By induction on the number of operations, starting with NEW, (L) and E(Adj)=EE(\mathit{Adj}) = E hold after each operation, and each query answers for the current edge set. ■\blacksquare

Back to Adjacency list