Data Structures and Algorithms in Java
GitHubAuthor
  • Preface
    • Syllabus
    • Schedule
  • 0. Getting Started
    • 0.1. Environment Setup
    • 0.2. Quiz
  • 1. Java Essentials
    • 1.1. Abstraction
    • 1.2. Implementation
    • 1.3. Unit Testing
    • 1.4. Quiz
  • 2. Priority Queues
    • 2.1. Simple Priority Queues
    • 2.2. Binary Heap
    • 2.3. Unit Testing
    • 2.4. Benchmarking
    • 2.5. Quiz
  • 3. Sorting Algorithms
    • 3.1. Abstraction
    • 3.2. Comparison-based Sort
    • 3.3. Divide & Conquer Sort
    • 3.4. Distribution-based Sort
    • 3.5. Quiz
    • 3.6. Homework
  • 4. Binary Search Trees
    • 4.1. Binary Search Trees
    • 4.2. Balanced BST
    • 4.2. AVL Trees
    • 4.3. Red-Black Trees
    • 4.4. Quiz
  • 5. Tries
    • 5.1. Concept
    • 5.2. Implementation
    • 5.3. Quiz
    • 5.4. Homework
  • 6. Disjoint Sets
    • 6.1. Concept
    • 6.2. Implementation
    • 6.3. Quiz
  • 7. Graphs
    • 7.1. Implementation
    • 7.2. Cycle Detection
    • 7.3. Topological Sorting
    • 7.4. Quiz
  • 8. Minimum Spanning Trees
    • 8.1. Abstraction
    • 8.2. Prim's Algorithm
    • 8.3. Kruskal’s Algorithm
    • 8.4. Edmonds' Algorithm
    • 8.5. Quiz
    • 8.6. Homework
  • 9. Network Flow
    • 9.1. Flow Network
    • 9.2. Ford-Fulkerson Algorithm
    • 9.3. Simplex Algorithm
    • 9.3. Quiz
  • 10. Dynamic Programming
    • 10.1. Fibonacci Sequence
    • 10.2. Tower of Hanoi
    • 10.3. Longest Common Subsequence
    • 10.4. Quiz
Powered by GitBook

©2023 Emory University - All rights reserved

On this page

Was this helpful?

Export as PDF
  1. 7. Graphs

7.2. Cycle Detection

This section describes an algorithm to detect a cycle in a graph.

Previous7.1. ImplementationNext7.3. Topological Sorting

Last updated 4 years ago

Was this helpful?

A cycle in a graph can be detected by traversing through the graph:

Let us define the containsCycle() method under the Graph class that returns true if the graph contains any cycle; otherwise, false:

public boolean containsCycle() {
    Deque<Integer> notVisited = IntStream.range(0, size()).boxed().collect(Collectors.toCollection(ArrayDeque::new));

    while (!notVisited.isEmpty()) {
        if (containsCycleAux(notVisited.poll(), notVisited, new HashSet<>()))
            return true;
    }

    return false;
}
  • L2: initially all vertices are not visited.

  • L4: iterates until all vertices are visitied:

    • L5-6: if the recursive call finds a cycle, returns true.

What is the worst-case complexity of the containsCycle() method?

private boolean containsCycleAux(int target, Deque<Integer> notVisited, Set<Integer> visited) {
    notVisited.remove(target);
    visited.add(target);

    for (Edge edge : getIncomingEdges(target)) {
        if (visited.contains(edge.getSource()))
            return true;

        if (containsCycleAux(edge.getSource(), notVisited, new HashSet<>(visited)))
            return true;
    }

    return false;
}
  • L2-3: marks the target vertex visited.

  • L5: for each incoming edge of the target vertex:

    • L6-7: returns true if the source vertex of this edge has seen before.

    • L9-10: returns true if the recursive call finds a cycle.

Why do we need to pass the new HashSet for every call in L5?