1. Doubly Linked List ์๋ฃ๊ตฌ์กฐ
https://ming412.tistory.com/159
Singly Linked List vs Doubly Linked List vs Circular Linked List ์๊ฐ๋ณต์ก๋ & ์ฌ์ฉ ์ฌ๋ก
Singly Linked List (๋จ์ผ ์ฐ๊ฒฐ ๋ฆฌ์คํธ) ๊ฐ ์์๊ฐ ๋ค์ ์์๋ง ๊ฐ๋ฆฌํค๋ ๋จ์ผ ๋ฐฉํฅ ๊ตฌ์กฐ์ด๋ค. ์๊ฐ ๋ณต์ก๋ ๊ฒ์ - ์ฒ์ ๋ ธ๋(head)๋ถํฐ ํ๋์ฉ ์ํํ๋ฉฐ ์ํ๋ ๊ฐ์ ์ฐพ์์ผ ํ๋ฏ๋ก O(n) ์ฝ์ - ์์์ ์
ming412.tistory.com
2. Doubly Linked List ์ง์ ๊ตฌํํ๊ธฐ
1) ADT (Abstract Data Type) ์ ์
- ๋ฐ์ดํฐ (Data)
- Node
- data: ๋ฐ์ดํฐ
- prev: ์ด์ ๋ ธ๋๋ฅผ ์ฐธ์กฐ
- next: ๋ค์ ๋ ธ๋๋ฅผ ์ฐธ์กฐ
- MyDoublyLinkedList
- head: ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ์ฒ์ ์์๋ฅผ ์ฐธ์กฐ
- tail: ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋ง์ง๋ง ์์๋ฅผ ์ฐธ์กฐ
- size: ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๊ธธ์ด
- ์์
- search(idx): ํน์ ์์น์ ๋ ธ๋ ๋ฐํ
- addFirst(e): ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋งจ ์์ ์์ ์ถ๊ฐ
- addLast(e): ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋งจ ๋ง์ง๋ง์ ์์ ์ถ๊ฐ
- add(idx, e): ํน์ ์์น์ ์์ ์ถ๊ฐ
- get(idx): ํน์ ์์น์ ๋ ธ๋์ ๊ฐ ๋ฐํ
- set(idx, e): ํน์ ์์น์ ์์๋ฅผ e๋ก ๋ณํ
- removeFirst(): ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋งจ ์ ์์ ์ญ์
- removeLast(): ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋งจ ๋ ์์ ์ญ์
- remove(idx): ํน์ ์์น์ ์์ ์ญ์
2) Node ํด๋์ค ์ ์
๋จ์ผ ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋ ธ๋๋ ๋ค์ ๋ ธ๋์ ์ฐธ์กฐ(next)๋ง ๊ฐ์ง๊ณ ์์๋ค.
ํ์ง๋ง ์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋ ธ๋๋ ๋จ์ผ ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋ ธ๋์ ๋ค๋ฅด๊ฒ ์ด์ ๋ ธ๋์ ์ฐธ์กฐ(prev)๋ ๊ฐ์ง๊ณ ์๋ค.
๋ฐ๋ผ์ data์ prev, next๋ฅผ ์ ์ธํด์ค๋ค.
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) MyDoublyLinkedList ํด๋์ค ์ ์
์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ head์ tail ํฌ์ธํฐ๋ก ํ์ฌ ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ์ ์ผ ์ฒซ ๋ ธ๋์ ๊ฐ์ฅ ๋ง์ง๋ง ๋ ธ๋๋ฅผ ์ฐธ์กฐํ๊ณ ์๋ค.
๋ฉค๋ฒ ๋ณ์๋ก size๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉด, ๋ฆฌ์คํธ์ ๊ธธ์ด๊ฐ ๊ถ๊ธํ ๋ ๋ชจ๋ ๋ ธ๋๋ฅผ ์ํํ๋ฉฐ ์นด์ดํธํ์ง ์์๋ ๋๊ธฐ ๋๋ฌธ์ ํธ๋ฆฌํ๋ค.
public class MyDoublyLinkedList<E> {
private Node<E> head;
private Node<E> tail;
private int size;
public MyDoublyLinkedList() {
this.head = null;
this.tail = null;
this.size = 0;
}
}
4) search ๊ตฌํ
search ๋ฉ์๋๋ add์ remove์์ ์ฌ์ฉ๋ ๋ด๋ถ ๋ฉ์๋์ด๋ค.
๋ ธ๋๋ฅผ ํน์ ์์น์ ์ถ๊ฐํ๊ฑฐ๋ ํน์ ์์น์ ์กด์ฌํ๋ ๋ ธ๋๋ฅผ ์ญ์ ํ ๋, ๋์ ๋ ธ๋๋ฅผ ๋จผ์ ์ฐพ์์ผ ํ๋ค.
๋์ ๋ ธ๋๋ฅผ ์ฐพ์ ๋ ์ฌ์ฉ๋ ์์ ์ด๋ค.
public Node<E> search(int idx) {
if (size < idx) {
throw new IndexOutOfBoundsException();
}
Node<E> cur = head;
for (int i=0; i<idx; i++) {
cur = cur.next;
}
return cur;
}
5) add ๊ตฌํ
addFirst - ๋ฆฌ์คํธ์ ๋งจ ์ฒ์์ ์์๋ฅผ ์ถ๊ฐํ๋ค.
๋จ์ผ ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ฅผ ๊ตฌํํ ๋์ ๋ง์ฐฌ๊ฐ์ง๋ก ํ์ฌ ๋ฆฌ์คํธ์ ๋ ธ๋๊ฐ ์กด์ฌํ๋์ง ํน์ ๋ฆฌ์คํธ๊ฐ ๋น์ด์๋์ง์ ๋ฐ๋ผ ๋ค๋ฅด๋ค.
ํ์ฌ ๋ฆฌ์คํธ๊ฐ ๋น์ด์๋ค๋ฉด head์ tail ๋ชจ๋๋ฅผ newNode๋ก ๊ฐฑ์ ํ๊ณ ,
๋น์ด์์ง ์๋ค๋ฉด newNode์ ๊ธฐ์กด head ๋ ธ๋๋ฅผ ์๋ฒฝํ ์ฐ๊ฒฐํด์ค ๋ค head ๋ ธ๋๋ฅผ newNode๋ก ๊ฐฑ์ ํด์ผ ํ๋ค.
"์๋ฒฝํ ์ฐ๊ฒฐํด์ค๋ค"๋ ๋ง์ ์๋ฏธ๋ ์๋ ๋ ๊ฐ์ง ์ ์ฐจ๋ฅผ ๋ชจ๋ ์ํํด์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
1. newNode์ next๊ฐ ๊ธฐ์กด head ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํ๋ค.
2. ๊ธฐ์กด head ๋ ธ๋์ prev๊ฐ newNode๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํ๋ค.
๋จ์ผ ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ฅผ ๊ตฌํํ ๋๋ ๋ฆฌ์คํธ๊ฐ ๋น์ด์์ง ์์์ง ํ์ธํ๊ธฐ ์ํด if (head != null) ์กฐ๊ฑด๋ฌธ์ ์ฌ์ฉํ๋๋ฐ,
์๋์ฒ๋ผ size๋ฅผ ์ด์ฉํด์ ํ์ธํ ์๋ ์๋ค.
public void addFirst(E data) {
Node<E> newNode = new Node<>(data);
if (size == 0) {
head = tail = newNode;
} else {
newNode.next = head; // newNode์ next๊ฐ ๊ธฐ์กด ์ฒซ ๋ฒ์งธ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก
head.prev = newNode; // ๊ธฐ์กด ์ฒซ ๋ฒ์งธ ๋
ธ๋์ prev๊ฐ newNode๋ฅผ ๊ฐ๋ฆฌํค๋๋ก
head = newNode; // head ๋
ธ๋ ๊ฐฑ์ (tail์ ๊ทธ๋๋ก)
}
size++;
}
addLast - ๋ฆฌ์คํธ์ ๋งจ ๋์ ์์๋ฅผ ์ถ๊ฐํ๋ค.
์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋ง์ง๋ง์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ ๋์๋ newNode์ ๊ธฐ์กด tail ๋ ธ๋๋ฅผ ์๋ฒฝํ ์ฐ๊ฒฐํด์ค ๋ค tail ๋ ธ๋๋ฅผ newNode๋ก ๊ฐฑ์ ํด์ผ ํ๋ค.
"์๋ฒฝํ ์ฐ๊ฒฐํด์ค๋ค"๋ ๋ง์ ์๋ฏธ๋ ์๋ ๋ ๊ฐ์ง ์ ์ฐจ๋ฅผ ๋ชจ๋ ์ํํด์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
1. newNode์ prev๊ฐ ๊ธฐ์กด tail ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํ๋ค.
2. ๊ธฐ์กด tail ๋ ธ๋์ next๊ฐ newNode๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํ๋ค.
public void addLast(E data) {
Node<E> newNode = new Node<>(data);
if (size == 0) {
head = tail = newNode;
} else {
newNode.prev = tail; // newNode์ prev๊ฐ ๊ธฐ์กด ๋ง์ง๋ง ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก
tail.next = newNode; // ๊ธฐ์กด ๋ง์ง๋ง ๋
ธ๋์ next๊ฐ newNode๋ฅผ ๊ฐ๋ฆฌํค๋๋ก
tail = newNode; // tail ๋
ธ๋ ๊ฐฑ์
}
size++;
}
add - ๋ฆฌ์คํธ์ ํน์ ์์น์ ์์๋ฅผ ์ถ๊ฐํ๋ค.
targetNode๋ newNode๊ฐ ์ฝ์ ๋๊ธฐ ์ํ๋ ์์น์ ์๋ ๋ ธ๋๋ฅผ ๋งํ๋ค.
๋ง์ฝ idx๊ฐ 0๋๋ size๋ผ๋ฉด ์์ ๋ง๋ค์๋ addFirst์ addLast๋ฅผ ํ์ฉํ ๊ฒ์ด๋ค.
๊ทธ๊ฒ ์๋๋ผ๋ฉด search(idx)๋ฅผ ํตํด targetNode๋ฅผ ์ฐพ๋๋ค.
์ฐ๊ฒฐ์ด ๋๊ธฐ์ง ์๋๋ก, targetNode์ ์ด์ (prev) ๋ ธ๋์ newNode๋ฅผ ๋จผ์ ์ฐ๊ฒฐํด์ผ ํ๋ค โ๏ธ
์ด๋ targetNode์ ์ด์ ๋ ธ๋์ next ์ฐธ์กฐ๊ฐ์ newNode๋ก ๋ณ๊ฒฝํด์ผ ํ๋๋ฐ, ํด๋น ์ฐ์ฐ์ด targetNode.prev.next = newNode ์ด๋ค.
๊ทธ๋ฆฌ๊ณ newNode์ targetNode๋ฅผ ์ฐ๊ฒฐํ๋ฉด ๋๋ค.
public void add(int idx, E data) {
Node<E> newNode = new Node<>(data);
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
if (idx == 0) {
addFirst(data);
} else if (idx == size) {
addLast(data);
} else {
Node<E> targetNode = search(idx);
// newNode์ targetNode์ ์ด์ ๋
ธ๋๋ฅผ ์ฐ๊ฒฐ
targetNode.prev.next = newNode;
newNode.prev = targetNode.prev;
// newNode์ targetNode๋ฅผ ์ฐ๊ฒฐ
targetNode.prev = newNode;
newNode.next = targetNode;
size++;
}
}
6) get ๊ตฌํ
get ํจ์๋ ํน์ ์์น์ ๋ ธ๋๋ฅผ ์ฐพ์ ๊ทธ ๊ฐ์ ๋ฐํํ๋ฉด ๋๋ค.
๋ฏธ๋ฆฌ ๋ง๋ค์ด๋ search ํจ์๋ฅผ ์ด์ฉํ๋ฉด ๋๊ณ , idx์ ๋ฒ์๊น์ง ๊ฒ์ฆํ์.
public E get(int idx) {
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
return search(idx).data;
}
7) set ๊ตฌํ
๋ง์ฐฌ๊ฐ์ง๋ก search ํจ์๋ฅผ ์ด์ฉํด์ idx ์์น์ ์๋ ๋ ธ๋๋ฅผ ๊ฐ์ ธ์จ ๋ค data ๊ฐ๋ง ๋ณ๊ฒฝํ๋ฉด ๋๋ค.
public void set(int idx, E data) {
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
search(idx).data = data;
}
8) remove ๊ตฌํ
removeFirst - ๋ฆฌ์คํธ์ ๋งจ ์ฒ์ ์์๋ฅผ ์ญ์ ํ๋ค.
๋งจ ์ฒ์ ์์๋ head ๋ ธ๋๋ฅผ ๋งํ๋ค.
head ๋ ธ๋๋ฅผ ์ญ์ ํ๋ค๋ ๊ฒ์, head ๋ ธ๋์ ๋ฐ๋ก ๋ค์ ๋ ธ๋๊ฐ ์๋ก์ด head ๋ ธ๋๊ฐ ๋๋ ๊ฒ์ด๋ค.
๋ฐ๋ผ์ head ๋ ธ๋์ ๋ค์(next) ๋ ธ๋์ prev๋ฅผ null๋ก ๋ณ๊ฒฝํด์ผ ํ๋ค. ํด๋น ์ฐ์ฐ์ด head.next.prev = null ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฆฌ์คํธ์ head ๊ฐ์ ๊ธฐ์กด head ๋ ธ๋์ ๋ฐ๋ก ๋ค์ ๋ ธ๋๋ก ๊ฐฑ์ ํ๋ฉด ๋๋ค.
public void removeFirst() {
if (size == 0) {
throw new IndexOutOfBoundsException();
}
head.next.prev = null; // head ๋
ธ๋์ head ๋
ธ๋์ ๋ค์ ๋
ธ๋์์ ์ฐ๊ฒฐ ๋๊ธฐ
head = head.next; // head ๋
ธ๋ ๊ฐฑ์
size--;
}
removeLast - ๋ฆฌ์คํธ์ ๋งจ ๋ ์์๋ฅผ ์ญ์ ํ๋ค.
๋งจ ๋ง์ง๋ง ์์๋ tail ๋ ธ๋๋ฅผ ๋งํ๋ค.
tail ๋ ธ๋๋ฅผ ์ญ์ ํ๋ค๋ ๊ฒ์, tail ๋ ธ๋์ ๋ฐ๋ก ์ ๋ ธ๋๊ฐ ์๋ก์ด tail ๋ ธ๋๊ฐ ๋๋ ๊ฒ์ด๋ค.
๋ฐ๋ผ์ tail ๋ ธ๋์ ์ด์ (prev) ๋ ธ๋์ next๋ฅผ null๋ก ๋ณ๊ฒฝํด์ผ ํ๋ค. ํด๋น ์ฐ์ฐ์ด tail.prev.next = null ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฆฌ์คํธ์ tail ๊ฐ์ ๊ธฐ์กด tail ๋ ธ๋์ ๋ฐ๋ก ์ ๋ ธ๋๋ก ๊ฐฑ์ ํ๋ฉด ๋๋ค.
public void removeLast() {
if (size == 0) {
throw new IndexOutOfBoundsException();
}
tail.prev.next = null; // tail ๋
ธ๋์ ์ด์ ๋
ธ๋์ tail ๋
ธ๋์ ์ฐ๊ฒฐ ๋๊ธฐ
tail = tail.prev; // head ๋
ธ๋ ๊ฐฑ์
size--;
}
remove - ๋ฆฌ์คํธ์ ํน์ ์์น์ ์์๋ฅผ ์ญ์ ํ๋ค.
targetNode๋ ์ญ์ ํ ๋ ธ๋๋ฅผ ๋งํ๋ค.
๋ง์ฝ idx๊ฐ 0๋๋ size๋ผ๋ฉด ์์ ๋ง๋ค์๋ removeFirst์ removeLast๋ฅผ ํ์ฉํ ๊ฒ์ด๋ค.
๊ทธ๊ฒ ์๋๋ผ๋ฉด search(idx)๋ฅผ ํตํด targetNode๋ฅผ ์ฐพ๋๋ค.
๋ ธ๋ ์ญ์ ๋, ์ญ์ ๋ ๋ ธ๋๋ฅผ ๊ณ ๋ฆฝ์ํค๋ฉด ๋๋ค.
์ฆ, ์ญ์ ๋ ๋ ธ๋์ ์/๋ค ๋ ธ๋์ ์ญ์ ๋ ๋ ธ๋์์ ์ฐ๊ฒฐ์ ๋๊ธฐ๋ง ํ๋ฉด ์ฐธ์กฐ๋์ง ์๋ ๋ ธ๋๋ GC๊ฐ ์ฒ๋ฆฌํด์ค๋ค.
targetNode ์ด์ ๋ ธ๋์ next๋ฅผ targetNode ๋ค์ ๋ ธ๋๋ก ์ฐ๊ฒฐํ๊ณ ,
targetNode ๋ค์ ๋ ธ๋์ prev๋ฅผ targetNode ์ด์ ๋ ธ๋๋ก ์ฐ๊ฒฐํด targetNode๋ฅผ ๊ณ ๋ฆฝ์ํจ๋ค.
public void remove(int idx) {
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
if (idx == 0) {
removeFirst();
} else if (idx == size - 1) {
removeLast();
} else {
Node<E> targetNode = search(idx);
targetNode.prev.next = targetNode.next; // targetNode ์ด์ ๋
ธ๋์ next๋ฅผ targetNode ๋ค์ ๋
ธ๋๋ก ์ฐ๊ฒฐ
targetNode.next.prev = targetNode.prev; // targetNode ๋ค์ ๋
ธ๋์ prev๋ฅผ targetNode ์ด์ ๋
ธ๋๋ก ์ฐ๊ฒฐ
size--;
}
}
9) toString ์ค๋ฒ๋ผ์ด๋ฉ
์๋์ฒ๋ผ toString์ ์ค๋ฒ๋ผ์ด๋ฉํ๋ฉด ๋๋ฒ๊น ํ๊ธฐ ์ข๋ค.
@Override
public String toString() {
Node<E> cur = head;
while (cur != null) {
System.out.print(cur.data + " ");
cur = cur.next;
}
System.out.println();
return "MyDoublyLinkedList{" +
"head=" + head.data +
", tail=" + tail.data +
", size=" + size +
'}';
}
10) ์ ์ฒด ์ฝ๋
package doubly;
import doubly.Node;
public class MyDoublyLinkedList<E> {
private Node<E> head;
private Node<E> tail;
private int size;
public MyDoublyLinkedList() {
this.head = null;
this.tail = null;
this.size = 0;
}
public Node<E> search(int idx) {
if (size < idx) {
throw new IndexOutOfBoundsException();
}
Node<E> cur = head;
for (int i=0; i<idx; i++) {
cur = cur.next;
}
return cur;
}
public void addFirst(E data) {
Node<E> newNode = new Node<>(data);
if (size == 0) {
head = tail = newNode;
} else {
newNode.next = head; // newNode์ next๊ฐ ๊ธฐ์กด ์ฒซ ๋ฒ์งธ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก
head.prev = newNode; // ๊ธฐ์กด ์ฒซ ๋ฒ์งธ ๋
ธ๋์ prev๊ฐ newNode๋ฅผ ๊ฐ๋ฆฌํค๋๋ก
head = newNode; // head ๋
ธ๋ ๊ฐฑ์ (tail์ ๊ทธ๋๋ก)
}
size++;
}
public void addLast(E data) {
Node<E> newNode = new Node<>(data);
if (size == 0) {
head = tail = newNode;
} else {
newNode.prev = tail; // newNode์ prev๊ฐ ๊ธฐ์กด ๋ง์ง๋ง ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก
tail.next = newNode; // ๊ธฐ์กด ๋ง์ง๋ง ๋
ธ๋์ next๊ฐ newNode๋ฅผ ๊ฐ๋ฆฌํค๋๋ก
tail = newNode; // tail ๋
ธ๋ ๊ฐฑ์
}
size++;
}
public void add(int idx, E data) {
Node<E> newNode = new Node<>(data);
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
if (idx == 0) {
addFirst(data);
} else if (idx == size) {
addLast(data);
} else {
Node<E> targetNode = search(idx);
// newNode์ targetNode์ ์ด์ ๋
ธ๋๋ฅผ ์ฐ๊ฒฐ
targetNode.prev.next = newNode;
newNode.prev = targetNode.prev;
// newNode์ targetNode๋ฅผ ์ฐ๊ฒฐ
targetNode.prev = newNode;
newNode.next = targetNode;
size++;
}
}
public E get(int idx) {
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
return search(idx).data;
}
public void set(int idx, E data) {
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
search(idx).data = data;
}
public void removeFirst() {
if (size == 0) {
throw new IndexOutOfBoundsException();
}
head.next.prev = null; // head ๋
ธ๋์ head ๋
ธ๋์ ๋ค์ ๋
ธ๋์์ ์ฐ๊ฒฐ ๋๊ธฐ
head = head.next; // head ๋
ธ๋ ๊ฐฑ์
size--;
}
public void removeLast() {
if (size == 0) {
throw new IndexOutOfBoundsException();
}
tail.prev.next = null; // tail ๋
ธ๋์ ์ด์ ๋
ธ๋์ tail ๋
ธ๋์ ์ฐ๊ฒฐ ๋๊ธฐ
tail = tail.prev; // head ๋
ธ๋ ๊ฐฑ์
size--;
}
public void remove(int idx) {
if (idx < 0 || idx > size) {
throw new IndexOutOfBoundsException();
}
if (idx == 0) {
removeFirst();
} else if (idx == size - 1) {
removeLast();
} else {
Node<E> targetNode = search(idx);
targetNode.prev.next = targetNode.next; // targetNode ์ด์ ๋
ธ๋์ next๋ฅผ targetNode ๋ค์ ๋
ธ๋๋ก ์ฐ๊ฒฐ
targetNode.next.prev = targetNode.prev; // targetNode ๋ค์ ๋
ธ๋์ prev๋ฅผ targetNode ์ด์ ๋
ธ๋๋ก ์ฐ๊ฒฐ
size--;
}
}
@Override
public String toString() {
Node<E> cur = head;
while (cur != null) {
System.out.print(cur.data + " ");
cur = cur.next;
}
System.out.println();
return "MyDoublyLinkedList{" +
"head=" + head.data +
", tail=" + tail.data +
", size=" + size +
'}';
}
}
public class Main {
public static void main(String[] args) {
MyDoublyLinkedList<String> linkedList = new MyDoublyLinkedList<>();
linkedList.addFirst("A");
linkedList.addFirst("B");
linkedList.addLast("C");
linkedList.addLast("D");
System.out.println(linkedList.toString());
linkedList.add(1, "E");
System.out.println(linkedList.toString());
System.out.println(linkedList.get(1));
linkedList.set(1, "F");
System.out.println(linkedList.toString());
linkedList.remove(3);
linkedList.remove(0);
System.out.println(linkedList.toString());
}
}