Skip to content

Commit 94389e7

Browse files
authored
Merge pull request #15 from BjornMelin/feat/0.1.0/linked-list
feat(linked-list): Implement LinkedLists and Recursive LinkedLists
2 parents d3fbd11 + 2dd3667 commit 94389e7

11 files changed

+3298
-0
lines changed
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
package data_structures.linear.linked_list;
2+
3+
/**
4+
* A class that implements a list of objects using a Circular Double Linked List
5+
*
6+
* @author bjornmelin
7+
* @param <T> Type of Object to Store in List
8+
*/
9+
public class CircularDoubleLinkedList<T> implements ListInterface<T> {
10+
11+
private Node firstNode;
12+
private int numberOfEntries;
13+
14+
/**
15+
* Default constructor for Circular Double Linked List
16+
*/
17+
public CircularDoubleLinkedList() {
18+
initializeDataFields();
19+
}
20+
21+
// Initializes the class's data fields to indicate an empty list.
22+
private void initializeDataFields() {
23+
firstNode = null;
24+
numberOfEntries = 0;
25+
}
26+
27+
/**
28+
* toString method for Circular Double Linked List
29+
*
30+
* @return String denoting all values in the list
31+
*/
32+
public String toString() {
33+
String output = "Data in the list(" + getLength() + "):\n";
34+
Node curr = firstNode;
35+
for (int i = 1; i <= numberOfEntries; i++) {
36+
output += "\t" + (i) + ":\t" + curr.data + "\n";
37+
curr = curr.next;
38+
}
39+
return output;
40+
}
41+
42+
@Override
43+
public void add(T newEntry) {
44+
Node newNode = new Node();
45+
newNode.data = newEntry;
46+
Node curr = firstNode;
47+
newNode.next = null;
48+
if (firstNode == null) {
49+
newNode.previous = newNode;
50+
firstNode = newNode;
51+
numberOfEntries++;
52+
return;
53+
}
54+
for (int i = 1; i < numberOfEntries; i++) {
55+
curr = curr.next;
56+
}
57+
if (numberOfEntries == 1) {
58+
newNode.previous = firstNode;
59+
} else {
60+
newNode.previous = curr;
61+
}
62+
curr.next = newNode;
63+
firstNode.previous = newNode;
64+
numberOfEntries++;
65+
}
66+
67+
@Override
68+
public void add(int newPosition, T newEntry) {
69+
if (newPosition >= numberOfEntries) {
70+
add(newEntry);
71+
} else if (newPosition <= 1) {
72+
Node newNode = new Node();
73+
newNode.data = newEntry;
74+
newNode.next = firstNode;
75+
firstNode.previous = newNode;
76+
firstNode = newNode;
77+
numberOfEntries++;
78+
Node curr = firstNode;
79+
for (int i = 1; i < numberOfEntries; i++) {
80+
curr = curr.next;
81+
}
82+
newNode.previous = curr;
83+
} else {
84+
Node curr = firstNode;
85+
for (int i = 1; i < newPosition - 1; i++) {
86+
curr = curr.next;
87+
}
88+
Node newNode = new Node();
89+
newNode.data = newEntry;
90+
newNode.next = curr.next;
91+
curr.next = newNode;
92+
newNode.previous = curr;
93+
if (curr.next.next != firstNode) {
94+
curr.next.next.previous = newNode;
95+
} else if (curr.next.next == firstNode) {
96+
curr.next.next = firstNode;
97+
}
98+
numberOfEntries++;
99+
}
100+
}
101+
102+
@Override
103+
public T remove(int givenPosition) {
104+
if (numberOfEntries == 0) {
105+
return null;
106+
}
107+
if (givenPosition >= numberOfEntries) {
108+
givenPosition = numberOfEntries;
109+
} else if (givenPosition <= 1) {
110+
givenPosition = 1;
111+
}
112+
if (givenPosition == 1) {
113+
Object temp = firstNode.data;
114+
firstNode = firstNode.next;
115+
firstNode.previous = null;
116+
numberOfEntries--;
117+
return (T) temp;
118+
}
119+
Node curr = firstNode;
120+
for (int i = 1; i < givenPosition - 1; i++) {
121+
curr = curr.next;
122+
}
123+
Object temp = curr.next.data;
124+
curr.next.next.previous = curr;
125+
curr.next = curr.next.next;
126+
numberOfEntries--;
127+
return (T) temp;
128+
}
129+
130+
@Override
131+
public void clear() {
132+
initializeDataFields();
133+
}
134+
135+
@Override
136+
public T replace(int givenPosition, T newEntry) {
137+
if (givenPosition <= 1) {
138+
Object temp = firstNode.data;
139+
firstNode.data = newEntry;
140+
return (T) temp;
141+
}
142+
if (givenPosition > numberOfEntries) {
143+
givenPosition = numberOfEntries;
144+
}
145+
Node curr = firstNode;
146+
for (int i = 1; i < givenPosition; i++) {
147+
curr = curr.next;
148+
}
149+
Object temp = curr.data;
150+
curr.data = newEntry;
151+
return (T) temp;
152+
}
153+
154+
@Override
155+
public T getEntry(int givenPosition) {
156+
if (numberOfEntries <= 0) {
157+
return null;
158+
} else if (givenPosition >= numberOfEntries) {
159+
givenPosition = numberOfEntries;
160+
} else if (givenPosition <= 1) {
161+
givenPosition = 1;
162+
}
163+
Node curr = firstNode;
164+
for (int i = 1; i < givenPosition; i++) {
165+
curr = curr.next;
166+
}
167+
return (T) curr.data;
168+
}
169+
170+
@Override
171+
public T[] toArray() {
172+
@SuppressWarnings("unchecked")
173+
T[] output = (T[]) new Object[numberOfEntries];
174+
Node curr = firstNode;
175+
for (int i = 1; i < numberOfEntries; i++) {
176+
output[i] = (T) curr.data;
177+
curr = curr.next;
178+
}
179+
return output;
180+
}
181+
182+
@Override
183+
public boolean contains(T anEntry) {
184+
Node curr = firstNode;
185+
while (curr != null) {
186+
for (int i = 1; i < numberOfEntries; i++) {
187+
if (curr.data == anEntry) {
188+
return true;
189+
}
190+
curr = curr.next;
191+
}
192+
}
193+
return false;
194+
}
195+
196+
@Override
197+
public int getLength() {
198+
return numberOfEntries;
199+
}
200+
201+
@Override
202+
public boolean isEmpty() {
203+
return numberOfEntries <= 0;
204+
}
205+
206+
@Override
207+
public void reverseData() {
208+
Node curr = firstNode;
209+
for (int i = 1; i < numberOfEntries; i++) {
210+
curr = curr.next;
211+
}
212+
System.out.println("The last item on the list is " + curr.data);
213+
System.out.println("Moving down the nodes in the list in reverse order: ");
214+
for (int i = 0; i < numberOfEntries; i++) {
215+
System.out.println("Present Node Data: " + curr.data);
216+
curr = curr.previous;
217+
}
218+
}
219+
220+
@Override
221+
public void circleTest() {
222+
System.out.println("We are testing the values to see if it is a circular loop.");
223+
System.out.println("Starting at the first node, we will loop backwards 2 times.");
224+
Node curr = firstNode;
225+
for (int i = 0; i < numberOfEntries * 2; i++) {
226+
System.out.println("Present Node Data: " + curr.data);
227+
curr = curr.previous;
228+
}
229+
}
230+
231+
private class Node {
232+
T data;
233+
Node next;
234+
Node previous;
235+
}
236+
237+
private Node getNodeAt(int givenPosition) {
238+
assert !isEmpty() && (1 <= givenPosition) && (givenPosition <= numberOfEntries);
239+
Node currentNode = firstNode;
240+
currentNode = find(0, givenPosition, currentNode);
241+
assert currentNode != null;
242+
return currentNode;
243+
}
244+
245+
private Node find(int count, int index, Node curr) {
246+
if (curr == null) {
247+
return null;
248+
}
249+
count++;
250+
if (count == index) {
251+
return curr;
252+
}
253+
return find(count, index, curr.next);
254+
}
255+
}

0 commit comments

Comments
 (0)