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