๐ง๐ป๐ป Doubly Linked List ์ง์ ๊ตฌํ with dummy head & dummy tail (JAVA)
https://ming412.tistory.com/167
๐ง๐ป๐ป Doubly Linked List ์ง์ ๊ตฌํ (JAVA)
1. Doubly Linked List ์๋ฃ๊ตฌ์กฐ https://ming412.tistory.com/159 Singly Linked List vs Doubly Linked List vs Circular Linked List ์๊ฐ๋ณต์ก๋ & ์ฌ์ฉ ์ฌ๋ก Singly Linked List (๋จ์ผ ์ฐ๊ฒฐ ๋ฆฌ์คํธ) ๊ฐ ์์๊ฐ ๋ค์ ์์๋ง ๊ฐ๋ฆฌํค๋ ๋จ
ming412.tistory.com
dummy node๋ฅผ ์ฌ์ฉํ์ง ์๊ณ Doubly Linked List๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ ๊ธ์ ์์ธํ ์ ์ด๋์๋ค.
์ด๋ฒ์๋ dummy node๋ฅผ ์ฌ์ฉํด์ ๊ฐ๋จํ search, add, remove ๋ฉ์๋๋ฅผ ๊ตฌํํ๊ณ ,
dummy node๋ฅผ ์ฌ์ฉํ์ ๋์ ์ฅ๋จ์ ์ ๋ํด ์์๋ณด์.
1. Doubly Linked List ์ง์ ๊ตฌํ (with. dummy head & dummy tail)
1) ADT (Abstract Data Type) ์ ์
- ๋ฐ์ดํฐ (Data)
- Node
- data: ๋ฐ์ดํฐ
- prev: ์ด์ ๋ ธ๋๋ฅผ ์ฐธ์กฐ
- next: ๋ค์ ๋ ธ๋๋ฅผ ์ฐธ์กฐ
- MyDoublyLinkedList
- dHead: ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ์ฒ์ ์์น์ dummy head ๋ ธ๋๋ฅผ ์ฐธ์กฐ
- dTail: ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋ง์ง๋ง ์์น์ dummy tail ๋ ธ๋๋ฅผ ์ฐธ์กฐ
- size: ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๊ธธ์ด
- ์์
- search(idx): ํน์ ์์น์ ๋ ธ๋ ๋ฐํ
- add(idx, e): ํน์ ์์น์ ์์ ์ถ๊ฐ
- remove(idx): ํน์ ์์น์ ์์ ์ญ์
2) Node ํด๋์ค ์ ์
Node ํด๋์ค๋ dummy node๋ฅผ ์ฌ์ฉํ์ง ์๊ณ Doubly Linked List๋ฅผ ๊ตฌํํ ๋์ ๋์ผํ๋ค.
public class Node<E> {
public E data;
public Node<E> prev;
public Node<E> next;
public Node(E data) {
this.data = data;
this.prev = null;
this.next = null;
}
}
3) DoublyLinkedList ํด๋์ค ์ ์
dummy node๋ฅผ ์ฌ์ฉํ์ง ์์์ ๋๋ `head`์ `tail`์ ๊ฐ์ง๊ณ ์์์ง๋ง, ์ง๊ธ์ `dHead`์ `dTail`์ ๊ฐ์ง๊ณ ์๋ค.
`head`์ `dHead`, ๊ทธ๋ฆฌ๊ณ `tail`๊ณผ `dTail`์ ์ฐจ์ด์ ์ ์๋์ ๊ฐ๋ค.
`head`: ์ค์ ์ฒซ ๋ ธ๋
`dHead`: ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ์ฒ์ ์์น์ ์๋ ๋ ธ๋๋ก, ์ ์๋ฏธํ ๊ฐ์ ๊ฐ์ง๊ณ ์๋ ์ฒซ ๋ ธ๋๋ `dHead.next`
`tail`: ์ค์ ๋ง์ง๋ง ๋ ธ๋
`dTail`: ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋ง์ง๋ง ์์น์ ์๋ ๋ ธ๋๋ก, ์ ์๋ฏธํ ๊ฐ์ ๊ฐ์ง๊ณ ์๋ ๋ง์ง๋ง ๋ ธ๋๋ `dTail.prev`
public class DoublyLinkedList<E> {
private Node<E> dHead; // dummyHead
private Node<E> dTail; // dummyTail
private int size;
public DoublyLinkedList() {
this.dHead = new Node<>();
this.dTail = new Node<>();
dHead.next = dTail;
dTail.prev = dHead;
}
}
4) search ๊ตฌํ
์ฐพ๊ณ ์ ํ๋ ๋ ธ๋(`idx`)๊ฐ ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ์ ๋ถ๋ถ์ ์กด์ฌํ๋์ง or ๋ท ๋ถ๋ถ์ ์กด์ฌํ๋์ง๋ก ๊ตฌ๋ถํ๋ค.
์ ๋ถ๋ถ์ ์กด์ฌํ๋ฉด `dHead`๋ถํฐ ์์๋๋ก ํ์ํ๊ณ , ๋ท ๋ถ๋ถ์ ์กด์ฌํ๋ฉด `dTail`๋ถํฐ ์ญ์์ผ๋ก ํ์ํ๋ค.
public Node<E> search(int idx) {
if (size < idx) {
throw new IndexOutOfBoundsException();
}
Node<E> cur;
if (idx < size/2) {
cur = dHead;
for (int i=-1; i<idx; i++) {
cur = cur.next;
}
} else {
cur = dTail;
for (int i=size; i>idx; i--) {
cur = cur.prev;
}
}
return cur;
}
5) add ๊ตฌํ
dummy node๋ฅผ ์ฌ์ฉํ์ง ์์์ ๋๋,
์๋ก์ด ๋ ธ๋๋ฅผ ์ถ๊ฐํ๊ณ ์ ํ๋ ์์น(`idx`)๊ฐ 0์ผ ๋(=๋งจ ์ฒ์), `size`์ผ ๋(=๋งจ ๋), ๋ ๋ค ์๋ ๋(=์ค๊ฐ ์์น)๋ก ๊ตฌ๋ถํ๋ค.
ํ์ง๋ง dummy node๋ฅผ ์ฌ์ฉํ๋ฉด, ์ฐ๊ฒฐ๋ฆฌ์คํธ์ ํญ์ `dHead`์ `dTail` ๋ ธ๋๊ฐ ์กด์ฌํ๋ฏ๋ก ๋ณ๋์ ์กฐ๊ฑด๋ฌธ ์์ด ์ผ๊ด์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
public void add(int idx, E data) {
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
Node<E> newNode = new Node<>(data);
Node<E> targetNode = search(idx);
// targetNode์ targetNode์ ๋ฐ๋ก ์ ๋
ธ๋ ์ฌ์ด์ newNode๋ฅผ ๋ผ์๋ฃ๋ ๊ฒ
newNode.next = targetNode; // newNode ๋ค์์ targetNode ์ฐ๊ฒฐ
newNode.prev = targetNode.prev; // newNode์ targetNode ์ ๋
ธ๋ ์ฐ๊ฒฐ
targetNode.prev.next = newNode; // targetNode์ ์ ๋
ธ๋์ newNode ์ฐ๊ฒฐ
targetNode.prev = newNode; // targetNode ์ ๋
ธ๋๋ฅผ newNode๋ก ๊ฐฑ์
size++;
}
6) remove ๊ตฌํ
๋ง์ฐฌ๊ฐ์ง๋ก, ๋งจ ์ฒ์ ๋ ธ๋๋ฅผ ์ญ์ ํ๋์ง ๋ง์ง๋ง ๋ ธ๋๋ฅผ ์ญ์ ํ๋์ง ์ค๊ฐ ๋ ธ๋๋ฅผ ์ญ์ ํ๋์ง์ ๋ฐ๋ผ ๋ถ๊ธฐํ ํ์๊ฐ ์๋ค.
์ฐ๊ฒฐ ๋ฆฌ์คํธ์์ ๋ ธ๋๋ฅผ ์ญ์ ํ๋ค๋ ๊ฒ์ ์ฐ๊ฒฐ์ ๋์ด ๊ณ ๋ฆฝ์ํค๋ ๊ฒ์ด๋ผ๊ณ ํ๋ค.
๋ฐ๋ผ์ ์ญ์ ํ ๋ ธ๋์ ์ด์ ๋ ธ๋์ ์ญ์ ํ ๋ ธ๋์ ๋ค์ ๋ ธ๋๋ฅผ ์๋ก ์ฐ๊ฒฐ์์ผ `targetNode`๋ฅผ ๊ณ ๋ฆฝ์ํค๋๋ก ๊ตฌํํ๋ค.
public void remove(int idx) {
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
Node<E> targetNode = search(idx); // ์ญ์ ํ ๋
ธ๋
// ์ญ์ ํ ๋
ธ๋์ ์ด์ ๋
ธ๋์ ์ญ์ ํ ๋
ธ๋์ ๋ค์ ๋
ธ๋๋ฅผ ์๋ก ์ฐ๊ฒฐ (์ญ์ ํ ๋
ธ๋ ๊ณ ๋ฆฝ)
targetNode.prev.next = targetNode.next;
targetNode.next.prev = targetNode.prev;
size--;
}
7) ์ ์ฒด ์ฝ๋
public class DoublyLinkedList<E> {
private Node<E> dHead; // dummyHead
private Node<E> dTail; // dummyTail
private int size;
public DoublyLinkedList() {
this.dHead = new Node<>();
this.dTail = new Node<>();
dHead.next = dTail;
dTail.prev = dHead;
}
public Node<E> search(int idx) {
if (size < idx) {
throw new IndexOutOfBoundsException();
}
Node<E> cur;
if (idx < size/2) {
cur = dHead;
for (int i=-1; i<idx; i++) {
cur = cur.next;
}
} else {
cur = dTail;
for (int i=size; i>idx; i--) {
cur = cur.prev;
}
}
return cur;
}
// dummy node๋ฅผ ์ฌ์ฉํ๋ฉด add ์ idx๊ฐ ๋งจ ์ฒ์/๋ง์ง๋ง์ผ ๊ฒฝ์ฐ ๋ฐ๋ก ๋ถ๋ฆฌํ์ง ์์๋ ๋๋ค.
public void add(int idx, E data) {
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
Node<E> newNode = new Node<>(data);
Node<E> targetNode = search(idx);
// targetNode์ targetNode์ ๋ฐ๋ก ์ ๋
ธ๋ ์ฌ์ด์ newNode๋ฅผ ๋ผ์๋ฃ๋ ๊ฒ
newNode.next = targetNode; // newNode ๋ค์์ targetNode ์ฐ๊ฒฐ
newNode.prev = targetNode.prev; // newNode์ targetNode ์ ๋
ธ๋ ์ฐ๊ฒฐ
targetNode.prev.next = newNode; // targetNode์ ์ ๋
ธ๋์ newNode ์ฐ๊ฒฐ
targetNode.prev = newNode; // targetNode ์ ๋
ธ๋๋ฅผ newNode๋ก ๊ฐฑ์
size++;
}
public void remove(int idx) {
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
Node<E> targetNode = search(idx);
targetNode.prev.next = targetNode.next;
targetNode.next.prev = targetNode.prev;
size--;
}
public void printAll() {
Node<E> cur = dHead;
System.out.print("dummy head - ");
while (cur.next != dTail) {
cur = cur.next;
System.out.print(cur.data + " - ");
}
System.out.println("dummy tail");
}
}
public class Main {
public static void main(String[] args) {
DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();
linkedList.add(0, "A");
linkedList.add(0, "B");
linkedList.printAll();
linkedList.add(1, "C");
linkedList.add(1, "D");
linkedList.printAll();
linkedList.add(4, "E");
linkedList.printAll();
System.out.println(linkedList.search(1).data);
linkedList.remove(3);
linkedList.printAll();
linkedList.remove(0);
linkedList.printAll();
}
}
2. dummy node๋ฅผ ์ฌ์ฉํ์ ๋์ ์ฅ๋จ์
์ฅ์
- ๋ ธ๋๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ ๋ ๋ณ๋์ ์กฐ๊ฑด๋ฌธ ์์ด ์ผ๊ด๋ ๋ฐฉ์์ผ๋ก ์ฐ์ฐ์ ์ํํ ์ ์๋ค.
- ํน๋ณํ ๊ฒฝ์ฐ(ex. ๋ฆฌ์คํธ๊ฐ ๋น์ด์์ ๋)๋ฅผ ์ฒ๋ฆฌํ ํ์๊ฐ ์์ผ๋ฏ๋ก ๋ฒ๊ทธ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ์ค์ด๋ ๋ค.
๋จ์
- ๋๋ฏธ ๋ ธ๋๋ค๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ๋ค.
- ์๋ฏธ ์๋ ๊ฐ์ด ์๋ ๋๋ฏธ ๊ฐ์ด ์ค์ ๋ฐ์ดํฐ์ ํจ๊ป ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ์กด์ฌํ๋ฏ๋ก ํท๊ฐ๋ฆด ์ ์๋ค.