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