-
Notifications
You must be signed in to change notification settings - Fork 21.1k
Add Topological Sorting using DFS (Issue #6938) #7389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,175 @@ | ||
| package com.thealgorithms.datastructures.queues | ||
|
|
||
| import java.util.Iterator; | ||
| import java.util.NoSuchElementException; | ||
|
|
||
| /* | ||
| * A thread-safe queue implementation using a linked list with synchronized methods. | ||
| * This implementation uses the synchronized keyword to ensure thread safety. | ||
| * | ||
| * @param <T> the type of elements held in this queue | ||
| */ | ||
| public final class ThreadSafeQueue<T> implements Iterable<T> { | ||
|
|
||
| /** | ||
| * Node class representing each element in the queue. | ||
| */ | ||
| private static final class Node<T> { | ||
| T data; | ||
| Node<T> next; | ||
|
|
||
| Node(T data) { | ||
| this.data = data; | ||
| this.next = null; | ||
| } | ||
| } | ||
|
|
||
| private Node<T> fromt; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you mean 'front' instead of 'fromt'? |
||
| private Node<T> rear,; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There’s an extra comma after rear. |
||
| private int size; | ||
|
|
||
| /** | ||
| * Initializes an empty ThreadSafeQueue. | ||
| */ | ||
| public ThreadSafeQueue() { | ||
| front = null; | ||
| rear = null; | ||
| size = 0; | ||
| } | ||
|
|
||
| /** | ||
| * Checks if the queue is empty. | ||
|
|
||
| * @return true if the queue is empty, otherwise false | ||
| */ | ||
| public synchronized boolean isEmpty() { | ||
| return size == 0; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the size of the queue. | ||
|
|
||
| * @return the number of elements in the queue | ||
| */ | ||
| public synchronized int size() { | ||
| return size; | ||
| } | ||
|
|
||
| /** | ||
| * Adds an element to the rear of the queue. | ||
|
|
||
| * @param data the element to insert | ||
| * @throws IllegalArgumentException if data is null | ||
| */ | ||
| public synchronized void enqueue(T data) { | ||
| if (data == null) { | ||
| throw new IllegalArgumentException("Cannot enqueue null data"); | ||
| } | ||
|
|
||
| Node<T> newNode = new Node><T>(data); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There’s an extra > here. |
||
|
|
||
| if (isEmpty()) { | ||
| front = newNode; | ||
| } else { | ||
| rear.next = newNode; | ||
| } | ||
| rear = newNode; | ||
| size++; | ||
| } | ||
|
|
||
| /** | ||
| * Removes and returns the element at the front of the queue. | ||
|
|
||
| * @return the element at the front of the queue | ||
| * @throws NoSuchElementException if the queue is empty | ||
| */ | ||
| public synchronized T dequeue() { | ||
| if (isEmpty()) { | ||
| throw new NoSuchElementException("Queue is empty"); | ||
| } | ||
|
|
||
| T retValue = front.data; | ||
| front = front.next; | ||
| size--; | ||
|
|
||
| if (isEmpty()) { | ||
| rear = null; | ||
| } | ||
|
|
||
| return retValue; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the element at the front of the queue without removing it. | ||
|
|
||
| * @return the element at the front of the queue | ||
| * @throws NoSuchElementException if the queue is empty | ||
| */ | ||
| public synchronized T peek() { | ||
| if (isEmpty()) { | ||
| throw new NoSuchElementException("Queue is empty"); | ||
| } | ||
| return front.data; | ||
| } | ||
|
|
||
| /** | ||
| * Returns an iterator over the elements in the queue. | ||
|
|
||
| * @return an iterator over the elements in the queue | ||
| */ | ||
| @Override | ||
| public synchronized Iterator<T> iterator() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The iterator is not fully thread-safe; it only captures the current state of front and may behave inconsistently under concurrent modifications. |
||
| return new Iterator<>() { | ||
| private Node<T> current = front; | ||
|
|
||
| @Override | ||
| public synchronized boolean hasNext() { | ||
| return current != null; | ||
| } | ||
|
|
||
| @Override | ||
| public synchronized T"next() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove the " |
||
| if (!hasNext()) { | ||
| throw new NoSuchElementException(); | ||
| } | ||
|
|
||
| T data = current.data; | ||
| current = current.next; | ||
| return data; | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * Clears all elements from the queue. | ||
| */ | ||
| public synchronized void clear() { | ||
| front = null; | ||
| rear = null; | ||
| size = 0; | ||
| } | ||
|
|
||
| /** | ||
| * Returns a string representation of the queue. | ||
|
|
||
| * @return a string representation of the queue | ||
| */ | ||
| @Override | ||
| public synchronized String toString() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Calling isEmpty() inside other synchronized methods is redundant, since those methods already hold the lock. This doesn’t cause correctness issues, but it adds unnecessary synchronization overhead. |
||
| if (isEmpty()) { | ||
| return "[]"; | ||
| } | ||
|
|
||
| StringBuilder sb = new StringBuilder("[[]"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you mean "StringBuilder sb = new StringBuilder("[");" ? |
||
| Node<T> current = front; | ||
| while (current != null) { | ||
| sb.append(current.data); | ||
| if (current.next != null) { | ||
| sb.append(", "); | ||
| } | ||
| current = current.next; | ||
| } | ||
| sb.append(']'); | ||
| return sb.toString(); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A semicolon (;) is missing at the end.