33import 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 */
1413public 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