Skip to content

Commit a4a46cd

Browse files
authored
Create CircularDoublyLinkedList.java
added circular doubly linked list code
1 parent c0bc709 commit a4a46cd

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package com.thealgorithms.datastructures.lists;
2+
3+
/**
4+
* This class is a circular doubly linked list implementation. In a circular
5+
* doubly linked list,
6+
* the last node points back to the first node and the first node points back to
7+
* the last node,
8+
* creating a circular chain in both directions.
9+
*
10+
* This implementation includes basic operations such as appending elements to
11+
* the end,
12+
* removing elements from a specified position, and converting the list to a
13+
* string representation.
14+
*
15+
* @param <E> the type of elements held in this list
16+
*/
17+
public class CircularDoublyLinkedList<E> {
18+
static final class Node<E> {
19+
Node<E> next;
20+
Node<E> prev;
21+
E value;
22+
23+
private Node(E value, Node<E> next, Node<E> prev) {
24+
this.value = value;
25+
this.next = next;
26+
this.prev = prev;
27+
}
28+
}
29+
30+
private int size;
31+
Node<E> head = null;
32+
33+
/**
34+
* Initializes a new circular doubly linked list. A dummy head node is used for
35+
* simplicity,
36+
* pointing initially to itself to ensure the list is never empty.
37+
*/
38+
public CircularDoublyLinkedList() {
39+
head = new Node<>(null, null, null);
40+
head.next = head;
41+
head.prev = head;
42+
size = 0;
43+
}
44+
45+
/**
46+
* Returns the current size of the list.
47+
*
48+
* @return the number of elements in the list
49+
*/
50+
public int getSize() {
51+
return size;
52+
}
53+
54+
/**
55+
* Appends a new element to the end of the list. Throws a NullPointerException
56+
* if
57+
* a null value is provided.
58+
*
59+
* @param value the value to append to the list
60+
* @throws NullPointerException if the value is null
61+
*/
62+
public void append(E value) {
63+
if (value == null) {
64+
throw new NullPointerException("Cannot add null element to the list");
65+
}
66+
Node<E> newNode = new Node<>(value, head, head.prev);
67+
head.prev.next = newNode;
68+
head.prev = newNode;
69+
size++;
70+
}
71+
72+
/**
73+
* Returns a string representation of the list in the format "[ element1,
74+
* element2, ... ]".
75+
* An empty list is represented as "[]".
76+
*
77+
* @return the string representation of the list
78+
*/
79+
public String toString() {
80+
if (size == 0) {
81+
return "[]";
82+
}
83+
StringBuilder sb = new StringBuilder("[ ");
84+
Node<E> current = head.next;
85+
while (current != head) {
86+
sb.append(current.value);
87+
if (current.next != head) {
88+
sb.append(", ");
89+
}
90+
current = current.next;
91+
}
92+
sb.append(" ]");
93+
return sb.toString();
94+
}
95+
96+
/**
97+
* Removes and returns the element at the specified position in the list.
98+
* Throws an IndexOutOfBoundsException if the position is invalid.
99+
*
100+
* @param pos the position of the element to remove
101+
* @return the value of the removed element - pop operation
102+
* @throws IndexOutOfBoundsException if the position is out of range
103+
*/
104+
public E remove(int pos) {
105+
if (pos >= size || pos < 0) {
106+
throw new IndexOutOfBoundsException("Position out of bounds");
107+
}
108+
Node<E> current = head.next;
109+
for (int i = 0; i < pos; i++) {
110+
current = current.next;
111+
}
112+
current.prev.next = current.next;
113+
current.next.prev = current.prev;
114+
E removedValue = current.value;
115+
current = null;
116+
size--;
117+
return removedValue;
118+
}
119+
120+
/**
121+
* A small demonstration of the above implemented circular doubly linked list
122+
* here we're initializing the circular doubly linked list, chronologically
123+
* adding and removing the linked list elements and demonstrating methods like
124+
* getSize()
125+
*/
126+
public static void main(String[] args) {
127+
CircularDoublyLinkedList<Integer> list = new CircularDoublyLinkedList<>();
128+
129+
System.out.println("Initial list: " + list);
130+
System.out.println("Initial size: " + list.getSize());
131+
132+
System.out.println("Appending 10, 20, 30.");
133+
list.append(10);
134+
list.append(20);
135+
list.append(30);
136+
137+
System.out.println("List content: " + list);
138+
System.out.println("List size: " + list.getSize());
139+
140+
System.out.println("Removing element at position 1.");
141+
int removed = list.remove(1);
142+
System.out.println("Removed element: " + removed);
143+
144+
System.out.println("List content after removal: " + list);
145+
System.out.println("List size after removal: " + list.getSize());
146+
147+
System.out.println("Removing element at position 0.");
148+
removed = list.remove(0);
149+
System.out.println("Removed element: " + removed);
150+
151+
System.out.println("List content after second removal: " + list);
152+
System.out.println("List size after second removal: " + list.getSize());
153+
154+
System.out.println("Appending 40.");
155+
list.append(40);
156+
157+
System.out.println("List content: " + list);
158+
System.out.println("List size: " + list.getSize());
159+
}
160+
}

0 commit comments

Comments
 (0)