1
1
package com .thealgorithms .datastructures .lists ;
2
2
3
+ /**
4
+ * This class is a circular singly linked list implementation. In a circular linked list,
5
+ * the last node points back to the first node, creating a circular chain.
6
+ *
7
+ * <p>This implementation includes basic operations such as appending elements
8
+ * to the end, removing elements from a specified position, and converting
9
+ * the list to a string representation.
10
+ *
11
+ * @param <E> the type of elements held in this list
12
+ */
3
13
public class CircleLinkedList <E > {
4
14
5
- private static final class Node <E > {
15
+ /**
16
+ * A static nested class representing a node in the circular linked list.
17
+ *
18
+ * @param <E> the type of element stored in the node
19
+ */
20
+ static final class Node <E > {
6
21
7
22
Node <E > next ;
8
23
E value ;
@@ -13,44 +28,56 @@ private Node(E value, Node<E> next) {
13
28
}
14
29
}
15
30
16
- // For better O.O design this should be private allows for better black box design
17
31
private int size ;
18
- // this will point to dummy node;
19
- private Node <E > head = null ;
20
- private Node <E > tail = null ; // keeping a tail pointer to keep track of the end of list
32
+ Node <E > head = null ;
33
+ private Node <E > tail ;
21
34
22
- // constructor for class.. here we will make a dummy node for circly linked list implementation
23
- // with reduced error catching as our list will never be empty;
35
+ /**
36
+ * Initializes a new circular linked list. A dummy head node is used for simplicity,
37
+ * pointing initially to itself to ensure the list is never empty.
38
+ */
24
39
public CircleLinkedList () {
25
- // creation of the dummy node
26
- head = new Node <E >(null , head );
40
+ head = new Node <>(null , head );
27
41
tail = head ;
28
42
size = 0 ;
29
43
}
30
44
31
- // getter for the size... needed because size is private.
45
+ /**
46
+ * Returns the current size of the list.
47
+ *
48
+ * @return the number of elements in the list
49
+ */
32
50
public int getSize () {
33
51
return size ;
34
52
}
35
53
36
- // for the sake of simplistiy this class will only contain the append function or addLast other
37
- // add functions can be implemented however this is the basses of them all really.
54
+ /**
55
+ * Appends a new element to the end of the list. Throws a NullPointerException if
56
+ * a null value is provided.
57
+ *
58
+ * @param value the value to append to the list
59
+ * @throws NullPointerException if the value is null
60
+ */
38
61
public void append (E value ) {
39
62
if (value == null ) {
40
- // we do not want to add null elements to the list.
41
63
throw new NullPointerException ("Cannot add null element to the list" );
42
64
}
43
- // head.next points to the last element;
44
65
if (tail == null ) {
45
- tail = new Node <E >(value , head );
66
+ tail = new Node <>(value , head );
46
67
head .next = tail ;
47
68
} else {
48
- tail .next = new Node <E >(value , head );
69
+ tail .next = new Node <>(value , head );
49
70
tail = tail .next ;
50
71
}
51
72
size ++;
52
73
}
53
74
75
+ /**
76
+ * Returns a string representation of the list in the format "[ element1, element2, ... ]".
77
+ * An empty list is represented as "[]".
78
+ *
79
+ * @return the string representation of the list
80
+ */
54
81
public String toString () {
55
82
if (size == 0 ) {
56
83
return "[]" ;
@@ -68,23 +95,27 @@ public String toString() {
68
95
return sb .toString ();
69
96
}
70
97
98
+ /**
99
+ * Removes and returns the element at the specified position in the list.
100
+ * Throws an IndexOutOfBoundsException if the position is invalid.
101
+ *
102
+ * @param pos the position of the element to remove
103
+ * @return the value of the removed element
104
+ * @throws IndexOutOfBoundsException if the position is out of range
105
+ */
71
106
public E remove (int pos ) {
72
107
if (pos >= size || pos < 0 ) {
73
- // catching errors
74
- throw new IndexOutOfBoundsException ("position cannot be greater than size or negative" );
108
+ throw new IndexOutOfBoundsException ("Position out of bounds" );
75
109
}
76
- // we need to keep track of the element before the element we want to remove we can see why
77
- // bellow.
110
+
78
111
Node <E > before = head ;
79
112
for (int i = 1 ; i <= pos ; i ++) {
80
113
before = before .next ;
81
114
}
82
115
Node <E > destroy = before .next ;
83
116
E saved = destroy .value ;
84
- // assigning the next reference to the element following the element we want to remove...
85
- // the last element will be assigned to the head.
86
- before .next = before .next .next ;
87
- // scrubbing
117
+ before .next = destroy .next ;
118
+
88
119
if (destroy == tail ) {
89
120
tail = before ;
90
121
}
0 commit comments