summaryrefslogtreecommitdiff
path: root/CircularLinkedList.java
blob: 7aa7d94330b0e8135a91a688a64cc1c41ae07b3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
import java.util.Iterator;

public class CircularLinkedList<E> implements Iterable<E>
{
	// Your variables
	Node<E> head;
	Node<E> tail;
	int size;  // BE SURE TO KEEP TRACK OF THE SIZE

	public CircularLinkedList()
	{
		head = null;
		tail = null;
		size = 0;
	}

	// I highly recommend using this helper method
	// Return Node<E> found at the specified index
	// be sure to handle out of bounds cases

	public boolean add(E item)
	{
		add(size,item);
		return true;
	}

	// Cases to handle
	// out of bounds
	// adding to empty list
	// adding to front
	// adding to "end"
	// adding anywhere else
	// REMEMBER TO INCREMENT THE SIZE
	public void add(int index, E item)
	{
		Node myNode = new Node(item);

		if (index < 0 || index > size)
		{
			throw new IndexOutOfBoundsException();
		}

		// adding to empty list
		if (size == 0)
		{
		        head = myNode;
		        tail = myNode;
			tail.next = head;
		}
		// adding to front
		else if (index == 0)
		{
		        myNode.next = head;
		        head = myNode;
		        tail.next = head;
		}
		// adding to "end" or anywhere else
		else
		{
			Node<E> current = head;

			for (int i = 0; i < index - 1; i++)
			{
				current = current.next;
			}

			myNode.next = current.next;
			current.next = myNode;
			if (index == size)
			{
				tail = myNode;
				tail.next = head;
			}
		}

		size++;
	}


	// remove must handle the following cases
	// out of bounds
	// removing the only thing in the list
	// removing the first thing in the list (need to adjust the last thing in the list to point to the beginning)
	// removing the last thing
	// removing any other node
	// REMEMBER TO DECREMENT THE SIZE
	public E remove(int index)
	{
		Node<E> myNode = null;

		if (index < 0 || index >= size)
		{
			throw new IndexOutOfBoundsException();
		}

		if (index == 0)
		{
			if (size == 1)
			{
				head = null;
				tail = null;
			}
			else
			{
				head = head.next;
				tail.next = head;
			}
		}
		else
		{
			Node<E> current = head;
			for (int i = 0; i < index - 1; i++)
			{
				current = current.next;
			}
			myNode = current.next;
			current.next = myNode.next;

			if (index == size - 1)
			{
				tail = current;
				tail.next = head;
			}
		}

		size--;
		return myNode.next.item;
	}

	// Turns your list into a string
	// Useful for debugging
	public String toString(){
		Node<E> current =  head;
		StringBuilder result = new StringBuilder();
		if(size == 0){
			return "";
		}
		if(size == 1) {
			return head.item.toString();

		}
		else{
			do{
				result.append(current.item);
				result.append(" ==> ");
				current = current.next;
			} while(current != head);
		}
		return result.toString();
	}


	public Iterator<E> iterator() {
		return new ListIterator<E>();
	}

	// provided code for different assignment
	// you should not have to change this
	// change at your own risk!
	// this class is not static because it needs the class it's inside of to survive!
	private class ListIterator<E> implements Iterator<E>{

		Node<E> nextItem;
		Node<E> prev;
		int index;

		@SuppressWarnings("unchecked")
		//Creates a new iterator that starts at the head of the list
		public ListIterator(){
			nextItem = (Node<E>) head;
			index = 0;
		}

		// returns true if there is a next node
		// this is always should return true if the list has something in it
		public boolean hasNext() {
			// TODO Auto-generated method stub
			return size != 0;
		}

		// advances the iterator to the next item
		// handles wrapping around back to the head automatically for you
		public E next() {
			// TODO Auto-generated method stub
			prev =  nextItem;
			nextItem = nextItem.next;
			index =  (index + 1) % size;
			return prev.item;

		}

		// removed the last node was visted by the .next() call
		// for example if we had just created a iterator
		// the following calls would remove the item at index 1 (the second person in the ring)
		// next() next() remove()
		public void remove() {
			int target;
			if(nextItem == head) {
				target = size - 1;
			} else{
				target = index - 1;
				index--;
			}
			CircularLinkedList.this.remove(target); //calls the above class
		}

	}

	// It's easiest if you keep it a singly linked list
	// SO DON'T CHANGE IT UNLESS YOU WANT TO MAKE IT HARDER
	private static class Node<E>
	{
		E item;
		Node<E> next;

		public Node(E item)
		{
			this.item = item;
		}

	}

	public static void main(String[] args)
	{

	}

}