...

Circular Doubly LinkedList ์๋ฃ๊ตฌ์กฐ
- ๊ธฐ์กด Doubly LinkedList์ ์ฒซ๋ฒ์งธ ๋ ธ๋์ ๋ง์ง๋ง ๋ ธ๋ ๋ผ๋ฆฌ ์๋ก ์ฐ๊ฒฐ ์์ผ, ์ํ ๋ฆฌ์คํธ ์ฒ๋ผ ๊ตฌ์ฑํ ์๋ฃ ๊ตฌ์กฐ
- ์ด๋ฌํ ์ํ ๊ตฌ์กฐ๋ ํฐ๋น ์ฑ๋์ ์ํํ๊ฑฐ๋ ์ค๋์ค ํ๋ ์ด์ด์ ๊ฐ์ด ๋ฐ์ดํฐ๋ฅผ ์์ฐจ์ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๋ค ๋ง์ง๋ง ์์๋ฅผ ๋ง๋๋ฉด ๋ค์ ์ฒ์ ์์๋ก ๋๋์๊ฐ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉ๋๋ค.
- ๋จ์ผ ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ฅผ ์ํ์ผ๋ก ์ฐ๊ฒฐํ Circular Singly linkedList๋ ์๋ค.

Circular Doubly LinkedList ๊ตฌํํ๊ธฐ (JAVA)
์ฐ์ ์๋ฐฉํฅ ์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ฅผ ๊ตฌํํ๊ธฐ ์์ ๋จผ์ Doubly LinkedList ์๋ฃ๊ตฌ์กฐ ๊ตฌํ์ ์ฐ์ต ํด๋ณด๊ณ ์ค๋ ๊ฒ์ ๊ถ์ฅํ๋ค. Circular Doubly LinkedList๋ ๊ธฐ์กด LinkedList์ ์๋์ ์ฐ๊ฒฐํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ '๋งํฌ๋' ๋ฆฌ์คํธ ๊ณจ์๋ ๊ฐ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ค๋ง ์๋ฐฉํฅ ์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋ ธ๋๋ฅผ ์ถ๊ฐ ๋ฐ ์ญ์ ํ๋ ๊ณผ์ ์์ ๊ฐ ๋ ธ๋๋ค์ ๋งํฌ ์ฒ๋ฆฌํ๋ ๋ด๋ถ ๋ก์ง์ด ์ฝ๊ฐ ๋ณ๊ฒฝ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๋จํ๋๋ผ๋ ์ด๋ฌํ ์๊ณ ๋ฆฌ์ฆ์ ์ง์ ์ฒดํ ์ฐ์ตํด ๋ณด๋ ๊ฒ์ด ์ข๋ค.
์์ผ๋ก ๊ตฌํํ ๋ฉ์๋๋ค์ ๋๋ถ๋ถ Doubly LinkedList ์๋ฃ๊ตฌ์กฐ์์ ๊ตฌํํ๊ฒ๊ณผ ๊ฒน์น๋ ์ต๋ํ ๋ถ๊ฐ์ ์ธ ์ค๋ช ์ ์๋ตํ๊ณ ๋ ธ๋ ์ํ ์ฐ๊ฒฐ์ ์ด์ ์ ๋ง์ถฐ ์ฐ์ฌํ ๊ฒ์ด๋ค. ๋ง์ผ ์์ธํ Doubly LinkedList์ ๋ํ ๊ตฌ์ฑ์ ํ์ตํ๊ณ ์ถ๋ค๋ฉด ์์ ์ด์ ํฌ์คํ ์ ์ฐธ๊ณ ํ๊ธธ ๋ฐ๋๋ค.
[DS] ๐งฑ Doubly LinkedList ์ง์ ๊ตฌํ ํด๋ณด๊ธฐ (JAVA)
Doubly LinkedList ์๋ฃ๊ตฌ์กฐ ๋ ธ๋(๊ฐ์ฒด)๋ฅผ ์ฐ๊ฒฐํ์ฌ ๋ฆฌ์คํธ ์ฒ๋ผ ๋ง๋ ์ปฌ๋ ์ (๋ฐฐ์ด์ด ์๋) ๋ ธ๋๋ค์ ์ฐ๊ฒฐํ์ฌ ๋ชฉ๋ก์ ๊ตฌ์ฑํ๊ธฐ์ ์ฉ๋(capacity) ๊ฐ๋ ์ด ์๋ค. (๋ฌดํ์ ์ ์ฅ ๊ฐ๋ฅ) ๋ฐ์ดํฐ์ ์ ์ฅ์์๊ฐ
inpa.tistory.com
๊ธฐ๋ณธ ํด๋์ค ๊ตฌ์กฐ ์ ์ํ๊ธฐ
ํด๋์ค ํ๋์ ์์ฑ์ ๊ทธ๋ฆฌ๊ณ ๋ฆฌ์คํธ์ ์ฐ์ผ ๋ ธ๋ ํด๋์ค๋ฅผ ์ ์ํด์ค๋ค.

public class CircularDoublyLinkedList<E> {
private Node<E> head; // ๋
ธ๋์ ์ฒซ ๋ถ๋ถ์ ๊ฐ๋ฆฌํค๋ ๋ ํผ๋ฐ์ค
private Node<E> tail; // ๋
ธ๋์ ๋ ๋ถ๋ถ์ ๊ฐ๋ฆฌํค๋ ๋ ํผ๋ฐ์ค
private int size; // ๋ฆฌ์คํธ ์์ ๊ฐฏ์
// ์์ฑ์
public CircularDoublyLinkedList() {
this.head = null;
this.tail = null;
this.size = 0;
}
// ๋
ธ๋ ํด๋์ค
private static class Node<E> {
private E item; // Node์ ๋ด์ ๋ฐ์ดํฐ
private Node<E> next; // ๋ค์ Node ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฅดํค๋ ๋ํผ๋ฐ์ค
private Node<E> prev; // ์ด์ Node ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฅดํค๋ ๋ํผ๋ฐ์ค
// ์์ฑ์ (์ด์ ๋
ธ๋ ํฌ์ธํธ | ๋ฐ์ดํฐ | ๋ค์ ๋
ธ๋ ํฌ์ธํธ)
Node(Node<E> prev, E item, Node<E> next) {
this.item = item;
this.next = next;
this.prev = prev;
}
}
// ...
}
add ๊ตฌํํ๊ธฐ
์๋ฐ์ LinkedList ํด๋์ค์ add ๋ฉ์๋ ์ข ๋ฅ๋ฅผ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด 4๊ฐ์ง๊ฐ ์กด์ฌํ๋ค.
- void addFirst(Object obj) : ์ฒซ๋ฒ์งธ ์์น์ ์์ ์ถ๊ฐ
- void addLast(Objec obj) : ๋ง์ง๋ง ์์น์ ์์ ์ถ๊ฐ
- boolean add(Object obj) : ๋ง์ง๋ง ์์น์ ์์ ์ถ๊ฐ (์ฑ๊ณตํ๋ฉด true)
- void add(int index, Object element) : ์ง์ ๋ ์์น์ ์์ ์ถ๊ฐ
์ด์ค์์ circular ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ฅผ ์ํ ์ถ๊ฐ ์์
์ ์งํํ ๋ฉ์๋๋ addFirst() ์ addLast() ์ด๋ค. ์๋ํ๋ฉด ์ฒ์๊ณผ ๋ง์ง๋ง ๋
ธ๋๊ฐ ์๋ก ์ํ์ผ๋ก ์ด์ด์ ธ์๊ธฐ ๋๋ฌธ์, ์ค๊ฐ ์ฝ์
๋ฉ์๋๋ ๊ธฐ์กด ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋ค๋ฅผ๋ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ง์ผ ๊ทธ ์ด์ธ์ ๋ฉ์๋ ๊ตฌํ๋ ์๊ณ ์ถ๋ค๋ฉด, ์ด์ LinkedList ๊ตฌํ ํฌ์คํ
์ ์ฐธ๊ณ ํ๊ธธ ๋ฐ๋๋ค.
addFirst ๊ตฌํ
public void addFirst(E value) {
// 1. head์ tail์ ์์ ๋ฐฑ์
ํจ
Node<E> first = head;
Node<E> last = tail;
// 2. ์ ๋
ธ๋๋ฅผ ์ถ๊ฐ (์ด๋ ์ฒซ๋ฒ์งธ ๋
ธ๋๋๊น prev๋ null์ด ๋๊ณ next๋ head๊ฐ ๊ฐ๋ฆฌํค๋ ๋
ธ๋๊ฐ ๋๊ฒ ๋๋ค)
Node<E> new_node = new Node<>(null, value, first);
// 3. ๋
ธ๋๋ฅผ ์ถ๊ฐํ์์ผ๋ ๋ฆฌ์คํธ ํฌ๊ธฐ ์ฆ๊ฐ
size++;
// 4. ์ฒซ๋ฒ์งธ ๊ธฐ์ค์ด ๋ณ๊ฒฝ๋์์ผ๋ head๋ฅผ ์ฝ์
๋ ์ ๋
ธ๋๋ก ์ฐธ์กฐํ๋๋ก ์
๋ฐ์ดํธ
head = new_node;
if (first == null) {
// 5. ๋ง์ผ ๋น ๋ฆฌ์คํธ์์ ์ต์ด์ ์์ ์ถ๊ฐ์์ ๊ฒฝ์ฐ,
tail = new_node; // tail๋ ์ฒซ์งธ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์
๋ฐ์ดํธ
// circular ์ฒ๋ฆฌ
new_node.next = new_node; // ์ถ๊ฐ ๋
ธ๋๋ ์๋ก ์๊ธฐ ์์ ์ ์ฐธ์กฐํ๊ฒ ๋จ
new_node.prev = new_node;
} else {
// 6. ๋ง์ผ ๋น ๋ฆฌ์คํธ๊ฐ ์๋๊ฒฝ์ฐ,
first.prev = new_node; // ์ถ๊ฐ๋๊ธฐ ์ด์ ์ฒซ๋ฒ์งธ์ด์๋ ๋
ธ๋์์ prev๋ฅผ ์ ๋
ธ๋๋ก ์ฐธ์กฐํ๋๋ก ์
๋ฐ์ดํธ
// circular ์ฒ๋ฆฌ
last.next = new_node; // ๋ง์ง๋ง ๋
ธ๋์ next๋ฅผ ์ถ๊ฐ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ฐธ์กฐ
new_node.prev = last; // ์ถ๊ฐ ๋
ธ๋(์ฒซ๋ฒ์งธ)์ prev๋ฅผ ๋ง์ง๋ง ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ฐธ์กฐ
}
}
๋ค์์ ๋น ๋ฆฌ์คํธ์ ์ต์ด์ ์ฝ์ ๊ณผ์ ์ ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ธ ๊ฒ์ด๋ค.
1. ๋จผ์ ๋น ๋ฆฌ์คํธ๊ฐ ๋ค์๊ณผ ๊ฐ์ด ์กด์ฌํ๋ค. (๋น์ด์์ผ๋๊น head์ tail์ ๊ฐ๊ฐ null์ด๋ค)

2. ์ฒซ๋ฒ์งธ ๋ ธ๋(head)์ ๋ง์ง๋ง ๋ ธ๋(tail)์ ๊ฐ๊ฐ fisrt์ last ๋ณ์์ ๋ฐฑ์ ํ๋ค.
3. ๊ทธ๋ฆฌ๊ณ ์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ๋ค. ์ด๋ ์ต์ด์ ๋ ธ๋์ด๊ธฐ ๋๋ฌธ์ next ์ prev ๋ชจ๋ null ์ด ๋๋ค.

4. head๊ฐ ์ฒซ๋ฒ์งธ์ธ ์ ๋ ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ ๋ฐ์ดํธ ํ๋ค.
5. ๋ฐฑ์ ํ first ๋ณ์์ ๊ฐ์ด null ์ด๋ฏ๋ก ์ด๋ ์ต์ด ์ฝ์ ๊ณผ์ ์ด ๋๊ฒ ๋์ด, tail๋ ์ ๋ ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ ๋ฐ์ดํธ ํ๋ค.

6. ๋ง์ง๋ง์ผ๋ก circular ์ฒ๋ฆฌ๋ฅผ ํ๋ค. ์ต์ด์ ์ฝ์ ๊ณผ์ ์ด๋ ํ๋์ ๋ ธ๋๋ ๊ฒฐ๊ตญ ์๊ธฐ ์์ ์ ์ฐธ์กฐํ๋ ๊ผด์ด ๋๊ฒ ๋๋ค.

๋ค์์ ์ด๋ฏธ ์์๊ฐ ์ฌ๋ฌ๊ฐ ๋ค์ด์๋ ๋ฆฌ์คํธ์ ์ฝ์ ๊ณผ์ ์ ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ธ ๊ฒ์ด๋ค.
1. ๋ค์๊ณผ ๊ฐ์ด ์์ 3๊ฐ๊ฐ ์กด์ฌํ๊ณ ์ฒซ๋ฒ์งธ ์์์ ๋ง์ง๋ง ์์๊ฐ ์๋ก ์ํ ์ฐธ์กฐํ๊ณ ์๋ค.

2. ์ฒซ๋ฒ์งธ ๋ ธ๋(head)์ ๋ง์ง๋ง ๋ ธ๋(tail)์ ๊ฐ๊ฐ fisrt์ last ๋ณ์์ ๋ฐฑ์ ํ๋ค.

3. ์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ๋ค. ์ด๋ ์ถ๊ฐ ๋ ธ๋์ next๋ first๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋๋ค.
4. ๊ทธ๋ฆฌ๊ณ head๋ฅผ ์ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ์ ๋ฐ์ดํธ ํ๋ค.

4. first๊ฐ null์ด ์๋๋ ์ต์ข ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด circular ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
5. ๋๋ฒ์งธ๊ฐ ๋ ๋ ธ๋(first)์ prev๋ ์ถ๊ฐ ๋ ธ๋์ ์ฐ๊ฒฐ
6. ๋ง์ง๋ง ๋ ธ๋(last)์ next๋ ์ถ๊ฐ ๋ ธ๋์ ์ฐ๊ฒฐ
7. ์ถ๊ฐ ๋ ธ๋์ prev๋ ๋ง์ง๋ง ๋ ธ๋(last)์ ์ฐ๊ฒฐ

addLast ๊ตฌํ
public void addLast(E value) {
// 1. head์ tail์ ์์ ๋ฐฑ์
ํจ
Node<E> first = head;
Node<E> last = tail;
// 2. ์ ๋
ธ๋๋ฅผ ์ถ๊ฐ (์ด๋ ๋ง์ง๋ง ๋
ธ๋๋๊น next๋ null์ด ๋๊ณ prev๋ tail์ด ๊ฐ๋ฆฌํค๋ ๋
ธ๋๊ฐ ๋๊ฒ ๋๋ค)
Node<E> new_node = new Node<>(last, value, null);
// 3. ๋
ธ๋๋ฅผ ์ถ๊ฐํ์์ผ๋ ๋ฆฌ์คํธ ํฌ๊ธฐ ์ฆ๊ฐ
size++;
// 4. ๋ง์ง๋ง ๋
ธ๋ ๊ธฐ์ค์ด ๋ณ๊ฒฝ๋์์ผ๋ tail์ ์ฝ์
๋ ์ ๋
ธ๋๋ก ์ฐธ์กฐํ๋๋ก ์
๋ฐ์ดํธ
tail = new_node;
if (last == null) {
// 5. ๋ง์ผ ๋น ๋ฆฌ์คํธ์์ ์ต์ด์ ์์ ์ถ๊ฐ์์ ๊ฒฝ์ฐ,
head = new_node; // tail๋ ์ฒซ์งธ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์
๋ฐ์ดํธ
// circular ์ฒ๋ฆฌ
new_node.next = new_node; // ์ถ๊ฐ ๋
ธ๋๋ ์๋ก ์๊ธฐ ์์ ์ ์ฐธ์กฐํ๊ฒ ๋จ
new_node.prev = new_node;
} else {
// 6. ๋ง์ผ ๋น ๋ฆฌ์คํธ๊ฐ ์๋๊ฒฝ์ฐ,
last.next = new_node; // ์ถ๊ฐ๋๊ธฐ ์ด์ ๋ง์ง๋ง์ด์๋ ๋
ธ๋์์ next๋ฅผ ์ ๋
ธ๋๋ก ์ฐธ์กฐํ๋๋ก ์
๋ฐ์ดํธ
// circular ์ฒ๋ฆฌ
new_node.next = first; // ์ถ๊ฐ ๋
ธ๋(๋ง์ง๋ง)์ next๋ฅผ ์ฒซ๋ฒ์งธ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ฐธ์กฐ
first.prev = new_node; // ์ฒซ๋ฒ์งธ ๋
ธ๋์ prev๋ฅผ ์ถ๊ฐ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ฐธ์กฐ
}
}
๋ค์์ ๋น ๋ฆฌ์คํธ์ ์ต์ด์ ์ฝ์ ๊ณผ์ ์ ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ธ ๊ฒ์ด๋ค.
1. ๋จผ์ ๋น ๋ฆฌ์คํธ๊ฐ ๋ค์๊ณผ ๊ฐ์ด ์กด์ฌํ๋ค. (๋น์ด์์ผ๋๊น head์ tail์ ๊ฐ๊ฐ null์ด๋ค)

2. ์ฒซ๋ฒ์งธ ๋ ธ๋(head)์ ๋ง์ง๋ง ๋ ธ๋(tail)์ ๊ฐ๊ฐ fisrt์ last ๋ณ์์ ๋ฐฑ์ ํ๋ค.
3. ๊ทธ๋ฆฌ๊ณ ์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ๋ค. ์ด๋ ์ต์ด์ ๋ ธ๋์ด๊ธฐ ๋๋ฌธ์ next ์ prev ๋ชจ๋ null ์ด ๋๋ค.

4. tail์ด ๋ง์ง๋ง์ธ ์ ๋ ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ ๋ฐ์ดํธ ํ๋ค.
5. ๋ฐฑ์ ํ last ๋ณ์์ ๊ฐ์ด null ์ด๋ฏ๋ก ์ด๋ ์ต์ด ์ฝ์ ๊ณผ์ ์ด ๋๊ฒ ๋์ด, first๋ ์ ๋ ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ ๋ฐ์ดํธ ํ๋ค.

6. ๋ง์ง๋ง์ผ๋ก circular ์ฒ๋ฆฌ๋ฅผ ํ๋ค. ์ต์ด์ ์ฝ์ ๊ณผ์ ์ด๋ ํ๋์ ๋ ธ๋๋ ๊ฒฐ๊ตญ ์๊ธฐ ์์ ์ ์ฐธ์กฐํ๋ ๊ผด์ด ๋๊ฒ ๋๋ค.

๋ค์์ ์ด๋ฏธ ์์๊ฐ ์ฌ๋ฌ๊ฐ ๋ค์ด์๋ ๋ฆฌ์คํธ์ ์ฝ์ ๊ณผ์ ์ ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ธ ๊ฒ์ด๋ค.
1. ๋ค์๊ณผ ๊ฐ์ด ์์ 3๊ฐ๊ฐ ์กด์ฌํ๊ณ ์ฒซ๋ฒ์งธ ์์์ ๋ง์ง๋ง ์์๊ฐ ์๋ก ์ํ ์ฐธ์กฐํ๊ณ ์๋ค.

2. ์ฒซ๋ฒ์งธ ๋ ธ๋(head)์ ๋ง์ง๋ง ๋ ธ๋(tail)์ ๊ฐ๊ฐ fisrt์ last ๋ณ์์ ๋ฐฑ์ ํ๋ค.

3. ์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ๋ค. ์ด๋ ์ถ๊ฐ ๋ ธ๋์ prev๋ last๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋๋ค.
4. ๊ทธ๋ฆฌ๊ณ tail์ ์ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ์ ๋ฐ์ดํธ ํ๋ค.

4. last๊ฐ null์ด ์๋๋ ์ต์ข ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด circular ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
5. ๋ง์ง๋ง ์ด์ ๋ ธ๋(last)์ next๋ ์ถ๊ฐ ๋ ธ๋์ ์ฐ๊ฒฐ
6. ์ฒซ๋ฒ์งธ ๋ ธ๋(first)์ prev๋ ์ถ๊ฐ ๋ ธ๋์ ์ฐ๊ฒฐ
7. ์ถ๊ฐ ๋ ธ๋์ next๋ ์ฒซ๋ฒ์งธ ๋ ธ๋(first)์ ์ฐ๊ฒฐ

remove ๊ตฌํํ๊ธฐ
LinkedList์ remove ๋ฉ์๋์๋ ๋ค์ ๋ค์ฏ๊ฐ์ง ์๋ค.
- Object removeFirst() : ๋งจ ์ ์์๋ฅผ ์ ๊ฑฐ (์ ๊ฑฐํ ์์๋ ๋ฐํ)
- Object remove() : ๋งจ ์ ์์๋ฅผ ์ ๊ฑฐ
- Object removeLast() : ๋งจ ๋ค ์์๋ฅผ ์ ๊ฑฐ
- Object remove(int index) : ์ธ๋ฑ์ค ์์น์ ์์๋ฅผ ์ ๊ฑฐ
- boolean remove(Object value) : ์์๊ฐ์ด ์ผ์นํ๋ ์์น์ ์์๋ฅผ ์ ๊ฑฐ (์ค๋ณต ์์๊ฐ์ด ์์ ๊ฒฝ์ฐ ๋งจ์์ ์์๊ฐ ์ ๊ฑฐ)
์ด์ค์์ ์ฐ๋ฆฌ๊ฐ ๊ตฌํํ ๋ฉ์๋๋ removeFirst() ์ removeLast() ์ด๋ค. ์ค๊ฐ ์ ๊ฑฐ ๊ณผ์ ์ ๋ด๋ถ์์ ์ธ๋ฑ์ค๊ฐ 0์ด๋ ๋ง์ง๋ง ์์น์ผ ๊ฒฝ์ฐ removeFirst() ์ removeLast() ๋ฅผ ์ฌํ์ฉํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด LinkedList ๊ตฌํ๊ณผ ๋ค๋ฅผ๋ฐ ์๋ค.
removeFirst ๊ตฌํ
public E removeFirst() {
// 1. ๋ง์ฝ ์ญ์ ํ ์์๊ฐ ์๋ฌด๊ฒ๋ ์์ผ๋ฉด ์๋ฌ
if (head == null) {
throw new RuntimeException();
}
// 2. ์ญ์ ๋ ์ฒซ๋ฒ์งธ ์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐฑ์
E returnValue = head.item;
// 3. ๋๋ฒ์งธ ๋
ธ๋๋ฅผ ์์ ์ ์ฅ
Node<E> first = head.next;
// 4. ์ฒซ๋ฒ์งธ ๋
ธ๋์ ๋ด๋ถ ์์๋ฅผ ๋ชจ๋ ์ญ์
head.next = null;
head.item = null;
// 5. head๊ฐ ๋ค์ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ์
๋ฐ์ดํธ
head = first;
// 6. ์์๊ฐ ์ญ์ ๋์์ผ๋ ํฌ๊ธฐ ๊ฐ์
size--;
// 7. ๋ง์ผ ๋ฆฌ์คํธ์ ์ ์ผํ ๊ฐ์ ์ญ์ ํด์ ๋น ๋ฆฌ์คํธ๊ฐ ๋ ๊ฒฝ์ฐ, tail๋ null ์ฒ๋ฆฌ
if (head == null) {
tail = null;
}
// 8. ๋ง์ง๋ง์ผ๋ก ์ญ์ ๋ ์์๋ฅผ ๋ฐํ
return returnValue;
}
1. ๋ฐํํ ์ญ์ ํ ๋ง์ง๋ง ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐฑ์ ํ๋ค.
2. ๋ง์ง๋ง ์์๊ฐ ์ญ์ ๊ฐ ๋๋ฉด ๋ง์ง๋ง ์ด์ ์์๊ฐ ๋ง์ง๋ง์ด๋๊ธฐ ๋๋ฌธ์ ๋ณ์ last์ ์ ์ฅํด์ ๋์ค์ ๋ค๋ฃจ๋๋ก ํ๋ค.
3. ์ถํ์ cicular ์ฒ๋ฆฌ๋ฅผ ์ํด ์ฒซ๋ฒ์งธ ์์๋ first์ ์ ์ฅํด์ค๋ค.

4. ๋ง์ง๋ง ๋ ธ๋์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ null๋ก ์ฒ๋ฆฌํ๋ค.

4. head์ ํฌ์ธํธ๋ฅผ first ๋ณ์์ ์ ์ฅํด๋์๋ ๋๋ฒ์งธ ๋ ธ๋(@200)์ผ๋ก ์ ๋ฐ์ดํธํ๋ค.
5. ๋ฆฌ์คํธ์ ์ฒซ๋ฒ์งธ ๋ ธ๋๊ฐ ๋ first์ ๋ ธ๋ prev๋ฅผ ๋ง์ง๋ง ๋ ธ๋(last)๋ก ์ฐ๊ฒฐํ๋ค.
6. ๋ฆฌ์คํธ์ ๋ง์ง๋ง ๋ ธ๋์ next๋ฅผ first๋ก ์ฐ๊ฒฐํ๋ค.
7. ์๋ฌด๊ฒ๋ ์ฐ๊ฒฐ๋์ง ์์ ๊ณ ์๊ฐ ๋๋ฒ๋ฆฐ ๋ ธ๋๋ ๋์ค์ GC๊ฐ ์๊ฑฐํด ๊ฐ๋ค.

+ ๋ง์ผ ์ญ์ ํ ์์๊ฐ ๋ฆฌ์คํธ์ ์ ์ผํ ์์๋ผ๋ฉด, ์ญ์ ํ ์ ๋น ๋ฆฌ์คํธ๊ฐ ๋๋ฏ๋ก head์ tail์ null์ด ๋๋๋ก ์ ๋ฐ์ดํธ ํด์ค๋ค.
removeLast ๊ตฌํ
1. ๋ฐํํ ์ญ์ ํ ๋ง์ง๋ง ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐฑ์ ํ๋ค.
2. ๋ง์ง๋ง ์์๊ฐ ์ญ์ ๊ฐ ๋๋ฉด ๋ง์ง๋ง ์ด์ (@200) ๋ ธ๋๊ฐ ๋ง์ง๋ง์ด ๋๊ธฐ ๋๋ฌธ์ ๋ง์ง๋ง ์ด์ ์์๋ฅผ ๋ณ์ last์ ์ ์ฅํด์ ๋์ค์ ๋ค๋ฃจ๋๋ก ํ๋ค.

3. ๋ง์ง๋ง ๋ ธ๋์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ null๋ก ์ฒ๋ฆฌํ๋ค.

4. tail์ ํฌ์ธํธ๋ฅผ last ๋ณ์์ ์ ์ฅํด๋์๋ ๋ง์ง๋ง ๋ ธ๋(@200)์ผ๋ก ์ ๋ฐ์ดํธํ๋ค.
5. ๋ฆฌ์คํธ์ ๋ง์ง๋ง ๋ ธ๋๊ฐ ๋ last์ ๋ ธ๋ next๋ฅผ ์ฒซ๋ฒ์งธ ๋ ธ๋(first)๋ก ์ฐ๊ฒฐํ๋ค.
6. ๋ฆฌ์คํธ์ ์ฒซ๋ฒ์งธ ๋ ธ๋์ prev๋ฅผ ๋ง์ง๋ง ๋ ธ๋๋ก ์ฐ๊ฒฐํ๋ค.
7. ์๋ฌด๊ฒ๋ ์ฐ๊ฒฐ๋์ง ์์ ๊ณ ์๊ฐ ๋๋ฒ๋ฆฐ ๋ ธ๋๋ ๋์ค์ GC๊ฐ ์๊ฑฐํด ๊ฐ๋ค.

+ ๋ง์ผ ์ญ์ ํ ์์๊ฐ ๋ฆฌ์คํธ์ ์ ์ผํ ์์๋ผ๋ฉด, ์ญ์ ํ ์ ๋น ๋ฆฌ์คํธ๊ฐ ๋๋ฏ๋ก head์ tail์ null์ด ๋๋๋ก ์ ๋ฐ์ดํธ ํด์ค๋ค.
toString ๊ตฌํ
๋ง์ง๋ง์ผ๋ก ๋งํฌ๋ ๋ฆฌ์คํธ ์์๋ค์ ์ถ๋ ฅํ๊ธฐ ์ํด Object ํด๋์ค์ toString() ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉ ํ์. ๊ทธ๋ฆฌ๊ณ ๋ค์๊ณผ ๊ฐ์ด ์ง์ ๋ฌธ์์ด ๋ํ๊ธฐ ์ฐ์ฐ์ผ๋ก๋ ๊ตฌํํ๋ค. ์ด๋ ์ฃผ์ํด์ผ ํ ์ ์ Circular LinkedList๋ ๋
ธ๋๊ฐ์ ๋ชจ๋ ์ฐธ์กฐ๊ฐ ๋์ด ์๊ธฐ ๋๋ฌธ์ next๋ prev๊ฐ null ์ผ ๊ฒฝ์ฐ์ ์๋ ์ฌ์ฉ ๋ชปํ๋ค. ๋ฐ๋ผ์ ๋ฆฌ์คํธ์ ์ฌ์ด์ฆ ๊น์ง ์ธ๋ฑ์ค ์ํ๋ก ๊ตฌ์ฑํด์ฃผ์ด์ผ ํ๋ค.
@Override
public String toString() {
if(head == null) {
return "[]";
}
Node<E> n = head;
String result = "[";
while(n.next != null) {
result += n.item + ", ";
n = n.next;
}
// n์ด ๋ง์ง๋ง์ผ ๊ฒฝ์ฐ n.next๊ฐ null์ด๋ ๋ฃจํ๋ฌธ์ ๋น ์ ธ๋์ค๊ฒ ๋์ ๋ง์ง๋ง ๋
ธ๋ ์ฝ์
์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ด์ผ ํ๋ค.
result += n.item + "]";
return result;
}
Circular LinkedList ์ปค์คํ toString
๊ธฐ์กด toString ์ฒ๋ผ ๋จ์ํ ๋ฐฐ์ด ๋ฌธ์์ด์ ์ฝ์์ ์ถ๋ ฅํ๋ ๊ฒ์ด ์๋, ๊ฐ ๋
ธ๋์ ๋งํฌ๋ ์ฃผ์์ ํจ๊ป ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ์ ์ฒด ์ฐธ์กฐ ์์๋ค์ ์ถ๋ ฅํด์ฃผ๋ ์ปค์คํ
toString() ๋ฉ์๋๋ฅผ ๋ง๋ค์ด ๋ณด์๋ค.

์ผ์ชฝ์ ํด๋น ๋ฆฌ์คํธ ์์ ๋
ธ๋์ ์ฃผ์ ํด์๊ฐ์ด๋ฉฐ, [์ด์ ๋
ธ๋ ์ฃผ์ | ๋
ธ๋ ์์ดํ
๊ฐ | ๋ค์ ๋
ธ๋ ์ฃผ์] ์์ผ๋ก ์์๋ฅผ ์ถ๋ ฅํ๋ค. ๋ง์ผ ๋
์๋ถ๋ค์ด ๊ตฌ์ถํ ๋ฉ์๋๊ฐ ์ ๋ง๋ก ๋งํฌ ์ฐ๊ฒฐ์ด ์ ๋์๋๋์ง ํ์ธํด๋ณด๊ณ ์ถ๋ค๋ฉด ์ด ์ปค์คํ
๋ฉ์๋๋ฅผ ํตํด ํ๋์ ๋
ธ๋ ์ฐธ์กฐ๋ฅผ ํ์ธํ ์ ์์ ๊ฒ์ด๋ค.
public String toString2() {
if (head == null) {
return "[]";
}
Node<E> n = head;
StringBuilder result = new StringBuilder();
result.append("[\n");
for(int i = 0; i< size; i++) {
result.append(" Node@").append(String.format("%-10s", n.hashCode())).append(" โ ");
if (n.prev != null) {
result.append("[").append(n.prev.hashCode()).append(" | ");
} else {
result.append("[").append("null").append(" | ");
}
result.append(n.item).append(" | ");
if (n.next != null) {
result.append(n.next.hashCode()).append("]");
} else {
result.append("null").append("]");
}
result.append(", \n");
n = n.next;
}
result.append("]");
return result.toString();
}
public static void main(String[] args) {
MyDoublyLinkedList<Number> list = new MyDoublyLinkedList<>();
list.addLast(2);
list.addFirst(1);
list.addLast(3);
list.add(2, 2.5);
System.out.println(list.toString2());
}
Circular Doubly LinkedList ๊ตฌํ ์ ์ฒด ์ฝ๋
public class CircularDoublyLinkedList<E> {
private Node<E> head; // ๋
ธ๋์ ์ฒซ ๋ถ๋ถ์ ๊ฐ๋ฆฌํค๋ ๋ ํผ๋ฐ์ค
private Node<E> tail; // ๋
ธ๋์ ๋ ๋ถ๋ถ์ ๊ฐ๋ฆฌํค๋ ๋ ํผ๋ฐ์ค
private int size; // ๋ฆฌ์คํธ ์์ ๊ฐฏ์
// ์์ฑ์
public CircularDoublyLinkedList() {
this.head = null;
this.tail = null;
this.size = 0;
}
// inner static class
private static class Node<E> {
private E item; // Node์ ๋ด์ ๋ฐ์ดํฐ
private Node<E> next; // ๋ค์ Node ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฅดํค๋ ๋ํผ๋ฐ์ค
private Node<E> prev; // ์ด์ Node ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฅดํค๋ ๋ํผ๋ฐ์ค
// ์์ฑ์ (์ด์ ๋
ธ๋ ํฌ์ธํธ | ๋ฐ์ดํฐ | ๋ค์ ๋
ธ๋ ํฌ์ธํธ)
Node(Node<E> prev, E item, Node<E> next) {
this.item = item;
this.next = next;
this.prev = prev;
}
}
private Node<E> search(int index) {
Node<E> n; // ๋ฐํํ ๋
ธ๋
if ((size / 2) > index) {
// 1. ๋ง์ผ ์ธ๋ฑ์ค๊ฐ ์์์ ๊ฐ๊น์ฐ๋ฉด, ์์ฐจ ํ์
n = head;
for (int i = 0; i < index; i++) {
n = n.next;
}
} else {
// 2. ๋ง์ผ ์ธ๋ฑ์ค๊ฐ ๋์ ๊ฐ๊น์ฐ๋ฉด, ์ญ์ ํ์
n = tail;
for (int i = size; i > index; i--) {
n = n.prev;
}
}
return n;
}
public void addFirst(E value) {
// 1. head์ tail์ ์์ ๋ฐฑ์
ํจ
Node<E> first = head;
Node<E> last = tail;
// 2. ์ ๋
ธ๋๋ฅผ ์ถ๊ฐ (์ด๋ ์ฒซ๋ฒ์งธ ๋
ธ๋๋๊น prev๋ null์ด ๋๊ณ next๋ head๊ฐ ๊ฐ๋ฆฌํค๋ ๋
ธ๋๊ฐ ๋๊ฒ ๋๋ค)
Node<E> new_node = new Node<>(null, value, first);
// 3. ๋
ธ๋๋ฅผ ์ถ๊ฐํ์์ผ๋ ๋ฆฌ์คํธ ํฌ๊ธฐ ์ฆ๊ฐ
size++;
// 4. ์ฒซ๋ฒ์งธ ๊ธฐ์ค์ด ๋ณ๊ฒฝ๋์์ผ๋ head๋ฅผ ์ฝ์
๋ ์ ๋
ธ๋๋ก ์ฐธ์กฐํ๋๋ก ์
๋ฐ์ดํธ
head = new_node;
if (first == null) {
// 5. ๋ง์ผ ๋น ๋ฆฌ์คํธ์์ ์ต์ด์ ์์ ์ถ๊ฐ์์ ๊ฒฝ์ฐ,
tail = new_node; // tail๋ ์ฒซ์งธ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์
๋ฐ์ดํธ
// circular ์ฒ๋ฆฌ
new_node.next = new_node; // ์ถ๊ฐ ๋
ธ๋๋ ์๋ก ์๊ธฐ ์์ ์ ์ฐธ์กฐํ๊ฒ ๋จ
new_node.prev = new_node;
} else {
// 6. ๋ง์ผ ๋น ๋ฆฌ์คํธ๊ฐ ์๋๊ฒฝ์ฐ,
first.prev = new_node; // ์ถ๊ฐ๋๊ธฐ ์ด์ ์ฒซ๋ฒ์งธ์ด์๋ ๋
ธ๋์์ prev๋ฅผ ์ ๋
ธ๋๋ก ์ฐธ์กฐํ๋๋ก ์
๋ฐ์ดํธ
// circular ์ฒ๋ฆฌ
last.next = new_node; // ๋ง์ง๋ง ๋
ธ๋์ next๋ฅผ ์ถ๊ฐ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ฐธ์กฐ
new_node.prev = last; // ์ถ๊ฐ ๋
ธ๋(์ฒซ๋ฒ์งธ)์ prev๋ฅผ ๋ง์ง๋ง ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ฐธ์กฐ
}
}
public void addLast(E value) {
// 1. head์ tail์ ์์ ๋ฐฑ์
ํจ
Node<E> first = head;
Node<E> last = tail;
// 2. ์ ๋
ธ๋๋ฅผ ์ถ๊ฐ (์ด๋ ๋ง์ง๋ง ๋
ธ๋๋๊น next๋ null์ด ๋๊ณ prev๋ tail์ด ๊ฐ๋ฆฌํค๋ ๋
ธ๋๊ฐ ๋๊ฒ ๋๋ค)
Node<E> new_node = new Node<>(last, value, null);
// 3. ๋
ธ๋๋ฅผ ์ถ๊ฐํ์์ผ๋ ๋ฆฌ์คํธ ํฌ๊ธฐ ์ฆ๊ฐ
size++;
// 4. ๋ง์ง๋ง ๋
ธ๋ ๊ธฐ์ค์ด ๋ณ๊ฒฝ๋์์ผ๋ tail์ ์ฝ์
๋ ์ ๋
ธ๋๋ก ์ฐธ์กฐํ๋๋ก ์
๋ฐ์ดํธ
tail = new_node;
if (last == null) {
// 5. ๋ง์ผ ๋น ๋ฆฌ์คํธ์์ ์ต์ด์ ์์ ์ถ๊ฐ์์ ๊ฒฝ์ฐ,
head = new_node; // tail๋ ์ฒซ์งธ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์
๋ฐ์ดํธ
// circular ์ฒ๋ฆฌ
new_node.next = new_node; // ์ถ๊ฐ ๋
ธ๋๋ ์๋ก ์๊ธฐ ์์ ์ ์ฐธ์กฐํ๊ฒ ๋จ
new_node.prev = new_node;
} else {
// 6. ๋ง์ผ ๋น ๋ฆฌ์คํธ๊ฐ ์๋๊ฒฝ์ฐ,
last.next = new_node; // ์ถ๊ฐ๋๊ธฐ ์ด์ ๋ง์ง๋ง์ด์๋ ๋
ธ๋์์ next๋ฅผ ์ ๋
ธ๋๋ก ์ฐธ์กฐํ๋๋ก ์
๋ฐ์ดํธ
// circular ์ฒ๋ฆฌ
first.prev = new_node; // ์ฒซ๋ฒ์งธ ๋
ธ๋์ prev๋ฅผ ์ถ๊ฐ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ฐธ์กฐ
new_node.next = first; // ์ถ๊ฐ ๋
ธ๋(๋ง์ง๋ง)์ next๋ฅผ ์ฒซ๋ฒ์งธ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ฐธ์กฐ
}
}
public boolean add(E value) {
addLast(value);
return true;
}
public void add(int index, E value) {
// 1. ์ธ๋ฑ์ค ๋ฒ์ ์ฒดํฌ
// ์ธ๋ฑ์ค๊ฐ 0๋ณด๋ค ์๊ฑฐ๋ size ๋ณด๋ค ํด ๊ฒฝ์ฐ ์๋ฌ
// (์ธ๋ฑ์ค๊ฐ size๋ณด๋ค ํฌ๋ฉด ๋ง์ง๋ง ์์ ๋ค์ ๋น๊ณต๊ฐ์ ๋ค์ ๋น๊ณต๊ฐ์ ๊ฐ๋ฆฌํค๋ ๊ฑฐ๋๊น)
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
// 2. ์ถ๊ฐํ๋ ค๋ index๊ฐ 0์ด๋ฉด addFirst ํธ์ถ
if (index == 0) {
addFirst(value);
return;
}
// 3. ์ถ๊ฐํ๋ ค๋ index๊ฐ size์ ๊ฐ์ผ๋ฉด addLast ํธ์ถ
if (index == size) {
addLast(value);
return;
}
// 4. ์ถ๊ฐํ๋ ค๋ ์์น์ ๋ค์ ๋
ธ๋ ์ป๊ธฐ
Node<E> next_node = search(index);
// 5. ์ถ๊ฐํ๋ ค๋ ์์น์ ์ด์ ๋
ธ๋ ์ป๊ธฐ
Node<E> prev_node = next_node.prev;
// 6. ์ ๋
ธ๋ ์์ฑ (๋ฐ๋ก ์ด์ / ๋ค์ ๋
ธ๋์ ์ฐ๊ฒฐ๋จ)
Node<E> new_node = new Node<>(prev_node, value, next_node);
// 7. ๋
ธ๋๋ฅผ ์ถ๊ฐํ์์ผ๋ ๋ฆฌ์คํธ ํฌ๊ธฐ ์ฆ๊ฐ
size++;
// 8. ์ด์ ๋
ธ๋์ next๋ฅผ ์ ๋
ธ๋์ ์ฐ๊ฒฐ
prev_node.next = new_node;
// 9. ๋ค์ ๋
ธ๋์ prev๋ฅผ ์ ๋
ธ๋์ ์ฐ๊ฒฐ
next_node.prev = new_node;
}
public E removeFirst() {
// 1. ๋ง์ฝ ์ญ์ ํ ์์๊ฐ ์๋ฌด๊ฒ๋ ์์ผ๋ฉด ์๋ฌ
if (head == null) {
throw new NoSuchElementException();
}
// 2. ์ญ์ ๋ ์ฒซ๋ฒ์งธ ์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐฑ์
E value = head.item;
// 3. ๋๋ฒ์งธ ๋
ธ๋์ ๋ง์ง๋ง ๋
ธ๋๋ฅผ ์์ ์ ์ฅ
Node<E> first = head.next;
Node<E> last = tail;
// 4. ์ฒซ๋ฒ์งธ ๋
ธ๋์ ๋ด๋ถ ์์๋ฅผ ๋ชจ๋ ์ญ์
head.next = null;
head.item = null;
head.prev = null;
// 5. ์์๊ฐ ์ญ์ ๋์์ผ๋ ํฌ๊ธฐ ๊ฐ์
size--;
// 6. head๊ฐ ๋ค์ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ์
๋ฐ์ดํธ
head = first;
if (first == null) {
// 7. ๋ง์ผ ๋ฆฌ์คํธ์ ์ ์ผํ ๊ฐ์ ์ญ์ ํด์ ๋น ๋ฆฌ์คํธ๊ฐ ๋ ๊ฒฝ์ฐ, tail๋ null ์ฒ๋ฆฌ
tail = null;
} else {
// 8. ๋ง์ผ ๋น ๋ฆฌ์คํธ๊ฐ ์๋๊ฒฝ์ฐ, circular ์ฒ๋ฆฌ
first.prev = last; // ์ญ์ ๋๊ธฐ ์ด์ ๋๋ฒ์งธ ์ด์๋ first๊ฐ ์ฒซ๋ฒ์งธ ๋
ธ๋๊ฐ ๋๋ prev๋ฅผ ๋ง์ง๋ง ๋
ธ๋์ ์ฐ๊ฒฐ
last.next = first; // ๋ง์ง๋ง ๋
ธ๋์ next๋ ์ฒซ๋ฒ์งธ ๋
ธ๋์ธ first์ ์ฐ๊ฒฐ
}
// 9. ๋ง์ง๋ง์ผ๋ก ์ญ์ ๋ ์์๋ฅผ ๋ฐํ
return value;
}
public E removeLast() {
// 1. ๋ง์ฝ ์ญ์ ํ ์์๊ฐ ์๋ฌด๊ฒ๋ ์์ผ๋ฉด ์๋ฌ
if (tail == null) {
throw new NoSuchElementException();
}
// 2. ์ญ์ ๋ ๋ง์ง๋ง ์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐฑ์
E value = tail.item;
// 3. ๋ง์ง๋ง ๋
ธ๋์ ์ด์ ๋
ธ๋์ ์ฒซ๋ฒ์งธ ๋
ธ๋๋ฅผ ์์ ์ ์ฅ
Node<E> last = tail.prev;
Node<E> first = head;
// 4. ๋ง์ง๋ง ๋
ธ๋์ ๋ด๋ถ ์์๋ฅผ ๋ชจ๋ ์ญ์
tail.item = null;
tail.prev = null;
tail.next = null;
// 5. ์์๊ฐ ์ญ์ ๋์์ผ๋ ํฌ๊ธฐ ๊ฐ์
size--;
// 6. tail์ด ์ด์ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ์
๋ฐ์ดํธ
tail = last;
if (last == null) {
// 7. ๋ง์ผ ๋ฆฌ์คํธ์ ์ ์ผํ ๊ฐ์ ์ญ์ ํด์ ๋น ๋ฆฌ์คํธ๊ฐ ๋ ๊ฒฝ์ฐ, head๋ null ์ฒ๋ฆฌ
head = null;
} else {
// 8. ๋ง์ผ ๋น ๋ฆฌ์คํธ๊ฐ ์๋๊ฒฝ์ฐ, circular ์ฒ๋ฆฌ
first.prev = last; // ์ญ์ ๋๊ธฐ ์ด์ ๋๋ฒ์งธ ์ด์๋ first๊ฐ ์ฒซ๋ฒ์งธ ๋
ธ๋๊ฐ ๋๋ prev๋ฅผ ๋ง์ง๋ง ๋
ธ๋์ ์ฐ๊ฒฐ
last.next = first; // ๋ง์ง๋ง ๋
ธ๋์ next๋ ์ฒซ๋ฒ์งธ ๋
ธ๋์ธ first์ ์ฐ๊ฒฐ
}
// 9. ๋ง์ง๋ง์ผ๋ก ์ญ์ ๋ ์์๋ฅผ ๋ฐํ
return value;
}
@Override
public String toString() {
if (head == null) {
return "[]";
}
Node<E> n = head;
String result = "[";
// circular ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ ๋
ธ๋์ next๊ฐ ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ธ๋ฑ์ค ์ฌ์ด์ฆ๋ก ์ํํ์ฌ์ผ ํ๋ค.
for (int i = 0; i < size; i++) {
result += n.item + ", ";
n = n.next;
}
// n์ด ๋ง์ง๋ง์ผ ๊ฒฝ์ฐ n.next๊ฐ null์ด๋ ๋ฃจํ๋ฌธ์ ๋น ์ ธ๋์ค๊ฒ ๋์ ๋ง์ง๋ง ๋
ธ๋ ์ฝ์
์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ด์ผ ํ๋ค.
result += n.item + "]";
return result;
}
public String toString2() {
if (head == null) {
return "[]";
}
Node<E> n = head;
StringBuilder result = new StringBuilder();
result.append("[\n");
int i = 0;
while (i < size) {
i++;
result.append(" Node@").append(String.format("%-10s", n.hashCode())).append(" โ ");
if (n.prev != null) {
result.append("[").append(n.prev.hashCode()).append(" | ");
} else {
result.append("[").append(n.prev).append(" | ");
}
result.append(n.item).append(" | ");
if (n.next != null) {
result.append(n.next.hashCode()).append("]");
} else {
result.append(n.next).append("]");
}
result.append(", \n");
n = n.next;
}
result.append("]");
return result.toString();
}
}
๋ง์ง๋ง์ผ๋ก ๋ด๊ฐ ์ง์ ์ง ์๋ฃ๊ตฌ์กฐ ํด๋์ค๊ฐ ์ ์์ ์ผ๋ก ์์ธ ์์ด ๋์ํ๋์ง ๋ฐ์ดํฐ ํ ์คํธ๋ฅผ ์์ง๋ง์!
public static void main(String[] args) {
CircularDoublyLinkedList<Number> list = new CircularDoublyLinkedList<>();
list.addFirst(3);
list.addFirst(2);
list.addFirst(1);
list.addLast(4);
list.add(3, 3.5);
list.add(1, 1.5);
System.out.println(list.toString2());
list.removeFirst();
list.removeFirst();
list.removeLast();
System.out.println(list.toString2());
}

# ์ฐธ๊ณ ์๋ฃ
https://www.alphacodingskills.com/ds/circular-doubly-linked-list.php
์ด ๊ธ์ด ์ข์ผ์ จ๋ค๋ฉด ๊ตฌ๋ & ์ข์์
์ฌ๋ฌ๋ถ์ ๊ตฌ๋
๊ณผ ์ข์์๋
์ ์์๊ฒ ํฐ ํ์ด ๋ฉ๋๋ค.