( mutable: MutableGraph<N, E, T>, nodeIndex: NodeIndex )
| 2358 | * @since 3.18.0 |
| 2359 | */ |
| 2360 | export const removeNode = <N, E, T extends Kind = "directed">( |
| 2361 | mutable: MutableGraph<N, E, T>, |
| 2362 | nodeIndex: NodeIndex |
| 2363 | ): void => { |
| 2364 | assertMutable(mutable) |
| 2365 | const impl = graphImpl(mutable) |
| 2366 | |
| 2367 | // Check if node exists |
| 2368 | if (!impl.nodes.has(nodeIndex)) { |
| 2369 | return // Node doesn't exist, nothing to remove |
| 2370 | } |
| 2371 | |
| 2372 | // Collect all incident edges for removal |
| 2373 | const edgesToRemove: Array<EdgeIndex> = [] |
| 2374 | |
| 2375 | // Get outgoing edges |
| 2376 | const outgoingEdges = impl.adjacency.get(nodeIndex) |
| 2377 | if (outgoingEdges !== undefined) { |
| 2378 | for (const edge of outgoingEdges) { |
| 2379 | edgesToRemove.push(edge) |
| 2380 | } |
| 2381 | } |
| 2382 | |
| 2383 | // Get incoming edges |
| 2384 | const incomingEdges = impl.reverseAdjacency.get(nodeIndex) |
| 2385 | if (incomingEdges !== undefined) { |
| 2386 | for (const edge of incomingEdges) { |
| 2387 | edgesToRemove.push(edge) |
| 2388 | } |
| 2389 | } |
| 2390 | |
| 2391 | // Remove all incident edges |
| 2392 | for (const edgeIndex of edgesToRemove) { |
| 2393 | removeEdgeInternal(impl, edgeIndex) |
| 2394 | } |
| 2395 | |
| 2396 | // Remove the node itself |
| 2397 | impl.nodes.delete(nodeIndex) |
| 2398 | impl.adjacency.delete(nodeIndex) |
| 2399 | impl.reverseAdjacency.delete(nodeIndex) |
| 2400 | |
| 2401 | // Only invalidate cycle flag if the graph wasn't already known to be acyclic |
| 2402 | // Removing nodes cannot introduce cycles in an acyclic graph |
| 2403 | invalidateCycleFlagOnRemoval(impl) |
| 2404 | } |
| 2405 | |
| 2406 | /** |
| 2407 | * Removes an edge from a mutable graph. |
no test coverage detected