Skip to content

Commit 1398b68

Browse files
authored
Merge branch 'master' into count_sll_improve
2 parents 0d5029a + ed35374 commit 1398b68

14 files changed

+763
-191
lines changed

DIRECTORY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,10 @@
831831
* [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java)
832832
* [CountSinglyLinkedListRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursionTest.java)
833833
* [CreateAndDetectLoopTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java)
834+
* [CursorLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CursorLinkedListTest.java)
835+
* [MergeKSortedLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/MergeKSortedLinkedListTest.java)
836+
* [MergeSortedArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/MergeSortedArrayListTest.java)
837+
* [MergeSortedSinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedListTest.java)
834838
* [QuickSortLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java)
835839
* [ReverseKGroupTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java)
836840
* [RotateSinglyLinkedListsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java)

src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
package com.thealgorithms.datastructures.lists;
22

3+
/**
4+
* CreateAndDetectLoop provides utility methods for creating and detecting loops
5+
* (cycles) in a singly linked list. Loops in a linked list are created by
6+
* connecting the "next" pointer of one node to a previous node in the list,
7+
* forming a cycle.
8+
*/
39
public final class CreateAndDetectLoop {
410

5-
// Node class representing a single node in the linked list
11+
/**
12+
* Private constructor to prevent instantiation of this utility class.
13+
*/
614
private CreateAndDetectLoop() {
715
throw new UnsupportedOperationException("Utility class");
816
}
17+
18+
/**
19+
* Node represents an individual element in the linked list, containing
20+
* data and a reference to the next node.
21+
*/
922
static final class Node {
1023
int data;
1124
Node next;
@@ -16,19 +29,16 @@ static final class Node {
1629
}
1730
}
1831

19-
// Method to create a loop between two specific positions in the linked list
20-
/*
21-
* Test case that shows the Cycle(loop) in a LinkedList
22-
* Let's take this linked list:
23-
* 1->2->3->4->5->6
24-
* \______/
25-
* In this linked list we can see there is a cycle.
26-
* we can create loop by calling createLoop function in main after creating LL
27-
* createLoop(head,2,5);
28-
* to detect there is loop or not we can call detectloop function in main
29-
* detectloop(head);
32+
/**
33+
* Creates a loop in a linked list by connecting the next pointer of a node
34+
* at a specified starting position (position2) to another node at a specified
35+
* destination position (position1). If either position is invalid, no loop
36+
* will be created.
37+
*
38+
* @param head the head node of the linked list
39+
* @param position1 the position in the list where the loop should end
40+
* @param position2 the position in the list where the loop should start
3041
*/
31-
3242
static void createLoop(Node head, int position1, int position2) {
3343
if (position1 == 0 || position2 == 0) {
3444
return;
@@ -39,29 +49,32 @@ static void createLoop(Node head, int position1, int position2) {
3949

4050
int count1 = 1;
4151
int count2 = 1;
42-
// Traverse to find node at position1
52+
// Traverse to the node at position1
4353
while (count1 < position1 && node1 != null) {
4454
node1 = node1.next;
4555
count1++;
4656
}
4757

48-
// Traverse to find node at position2
58+
// Traverse to the node at position2
4959
while (count2 < position2 && node2 != null) {
5060
node2 = node2.next;
5161
count2++;
5262
}
5363

54-
// Create a loop by connecting node2's next to node1
64+
// If both nodes are valid, create the loop
5565
if (node1 != null && node2 != null) {
5666
node2.next = node1;
5767
}
5868
}
59-
// Method to detect a loop in the linked list
69+
6070
/**
61-
* Detects the presence of a loop in the linked list.
71+
* Detects the presence of a loop in the linked list using Floyd's cycle-finding
72+
* algorithm, also known as the "tortoise and hare" method.
6273
*
63-
* @see <a href="https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare">Floyd's Cycle Detection Algorithm</a>
64-
* @return true if loop exists else false
74+
* @param head the head node of the linked list
75+
* @return true if a loop is detected, false otherwise
76+
* @see <a href="https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare">
77+
* Floyd's Cycle Detection Algorithm</a>
6578
*/
6679
static boolean detectLoop(Node head) {
6780
Node sptr = head;

src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java

Lines changed: 83 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@
33
import java.util.Objects;
44

55
/**
6-
* This class implements a Cursor Linked List.
7-
*
8-
* A CursorLinkedList is an array version of a Linked List. Essentially you have
9-
* an array of list nodes but instead of each node containing a pointer to the
10-
* next item in the linked list, each node element in the array contains the
11-
* index for the next node element.
6+
* CursorLinkedList is an array-based implementation of a singly linked list.
7+
* Each node in the array simulates a linked list node, storing an element and
8+
* the index of the next node. This structure allows for efficient list operations
9+
* without relying on traditional pointers.
1210
*
11+
* @param <T> the type of elements in this list
1312
*/
1413
public class CursorLinkedList<T> {
1514

15+
/**
16+
* Node represents an individual element in the list, containing the element
17+
* itself and a pointer (index) to the next node.
18+
*/
1619
private static class Node<T> {
17-
1820
T element;
1921
int next;
2022

@@ -31,20 +33,26 @@ private static class Node<T> {
3133
private static final int CURSOR_SPACE_SIZE = 100;
3234

3335
{
34-
// init at loading time
36+
// Initialize cursor space array and free list pointers
3537
cursorSpace = new Node[CURSOR_SPACE_SIZE];
3638
for (int i = 0; i < CURSOR_SPACE_SIZE; i++) {
3739
cursorSpace[i] = new Node<>(null, i + 1);
3840
}
3941
cursorSpace[CURSOR_SPACE_SIZE - 1].next = 0;
4042
}
4143

44+
/**
45+
* Constructs an empty CursorLinkedList with the default capacity.
46+
*/
4247
public CursorLinkedList() {
4348
os = 0;
4449
count = 0;
4550
head = -1;
4651
}
4752

53+
/**
54+
* Prints all elements in the list in their current order.
55+
*/
4856
public void printList() {
4957
if (head != -1) {
5058
int start = head;
@@ -57,27 +65,36 @@ public void printList() {
5765
}
5866

5967
/**
60-
* @return the logical index of the element within the list , not the actual
61-
* index of the [cursorSpace] array
68+
* Finds the logical index of a specified element in the list.
69+
*
70+
* @param element the element to search for in the list
71+
* @return the logical index of the element, or -1 if not found
72+
* @throws NullPointerException if element is null
6273
*/
6374
public int indexOf(T element) {
64-
Objects.requireNonNull(element);
65-
Node<T> iterator = cursorSpace[head];
66-
for (int i = 0; i < count; i++) {
67-
if (iterator.element.equals(element)) {
68-
return i;
75+
if (element == null) {
76+
throw new NullPointerException("Element cannot be null");
77+
}
78+
try {
79+
Objects.requireNonNull(element);
80+
Node<T> iterator = cursorSpace[head];
81+
for (int i = 0; i < count; i++) {
82+
if (iterator.element.equals(element)) {
83+
return i;
84+
}
85+
iterator = cursorSpace[iterator.next];
6986
}
70-
iterator = cursorSpace[iterator.next];
87+
} catch (Exception e) {
88+
return -1;
7189
}
72-
7390
return -1;
7491
}
7592

7693
/**
77-
* @param position , the logical index of the element , not the actual one
78-
* within the [cursorSpace] array . this method should be used to get the
79-
* index give by indexOf() method.
80-
* @return
94+
* Retrieves an element at a specified logical index in the list.
95+
*
96+
* @param position the logical index of the element
97+
* @return the element at the specified position, or null if index is out of bounds
8198
*/
8299
public T get(int position) {
83100
if (position >= 0 && position < count) {
@@ -88,51 +105,76 @@ public T get(int position) {
88105
if (counter == position) {
89106
return element;
90107
}
91-
92108
start = cursorSpace[start].next;
93109
counter++;
94110
}
95111
}
96-
97112
return null;
98113
}
99114

115+
/**
116+
* Removes the element at a specified logical index from the list.
117+
*
118+
* @param index the logical index of the element to remove
119+
*/
100120
public void removeByIndex(int index) {
101121
if (index >= 0 && index < count) {
102122
T element = get(index);
103123
remove(element);
104124
}
105125
}
106126

127+
/**
128+
* Removes a specified element from the list.
129+
*
130+
* @param element the element to be removed
131+
* @throws NullPointerException if element is null
132+
*/
107133
public void remove(T element) {
108134
Objects.requireNonNull(element);
109-
110-
// case element is in the head
111135
T tempElement = cursorSpace[head].element;
112136
int tempNext = cursorSpace[head].next;
113137
if (tempElement.equals(element)) {
114138
free(head);
115139
head = tempNext;
116-
} else { // otherwise cases
140+
} else {
117141
int prevIndex = head;
118142
int currentIndex = cursorSpace[prevIndex].next;
119-
120143
while (currentIndex != -1) {
121144
T currentElement = cursorSpace[currentIndex].element;
122145
if (currentElement.equals(element)) {
123146
cursorSpace[prevIndex].next = cursorSpace[currentIndex].next;
124147
free(currentIndex);
125148
break;
126149
}
127-
128150
prevIndex = currentIndex;
129151
currentIndex = cursorSpace[prevIndex].next;
130152
}
131153
}
132-
133154
count--;
134155
}
135156

157+
/**
158+
* Allocates a new node index for storing an element.
159+
*
160+
* @return the index of the newly allocated node
161+
* @throws OutOfMemoryError if no space is available in cursor space
162+
*/
163+
private int alloc() {
164+
int availableNodeIndex = cursorSpace[os].next;
165+
if (availableNodeIndex == 0) {
166+
throw new OutOfMemoryError();
167+
}
168+
cursorSpace[os].next = cursorSpace[availableNodeIndex].next;
169+
cursorSpace[availableNodeIndex].next = -1;
170+
return availableNodeIndex;
171+
}
172+
173+
/**
174+
* Releases a node back to the free list.
175+
*
176+
* @param index the index of the node to release
177+
*/
136178
private void free(int index) {
137179
Node<T> osNode = cursorSpace[os];
138180
int osNext = osNode.next;
@@ -141,44 +183,26 @@ private void free(int index) {
141183
cursorSpace[index].next = osNext;
142184
}
143185

186+
/**
187+
* Appends an element to the end of the list.
188+
*
189+
* @param element the element to append
190+
* @throws NullPointerException if element is null
191+
*/
144192
public void append(T element) {
145193
Objects.requireNonNull(element);
146194
int availableIndex = alloc();
147195
cursorSpace[availableIndex].element = element;
148-
149196
if (head == -1) {
150197
head = availableIndex;
198+
} else {
199+
int iterator = head;
200+
while (cursorSpace[iterator].next != -1) {
201+
iterator = cursorSpace[iterator].next;
202+
}
203+
cursorSpace[iterator].next = availableIndex;
151204
}
152-
153-
int iterator = head;
154-
while (cursorSpace[iterator].next != -1) {
155-
iterator = cursorSpace[iterator].next;
156-
}
157-
158-
cursorSpace[iterator].next = availableIndex;
159205
cursorSpace[availableIndex].next = -1;
160-
161206
count++;
162207
}
163-
164-
/**
165-
* @return the index of the next available node
166-
*/
167-
private int alloc() {
168-
// 1- get the index at which the os is pointing
169-
int availableNodeIndex = cursorSpace[os].next;
170-
171-
if (availableNodeIndex == 0) {
172-
throw new OutOfMemoryError();
173-
}
174-
175-
// 2- make the os point to the next of the @var{availableNodeIndex}
176-
cursorSpace[os].next = cursorSpace[availableNodeIndex].next;
177-
178-
// this to indicate an end of the list , helpful at testing since any err
179-
// would throw an outOfBoundException
180-
cursorSpace[availableNodeIndex].next = -1;
181-
182-
return availableNodeIndex;
183-
}
184208
}

0 commit comments

Comments
 (0)