Search

๋‹จ์ˆœ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ

๋‹จ์ˆœ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ

๊ฐœ๋…

โ€ข
๋‹จ์ˆœ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ(Singly Linked List) ๋Š” ๊ฐ ๋…ธ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ(data) ์™€ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฐธ์กฐ(next) ๋ฅผ ๊ฐ–๋Š” ์„ ํ˜• ์ž๋ฃŒ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.
โ€ข
๋ฐฐ์—ด๊ณผ ๋‹ฌ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์—ฐ์†์ผ ํ•„์š”๊ฐ€ ์—†๊ณ , ๋…ธ๋“œ๋“ค์ด ํฌ์ธํ„ฐ(์ฐธ์กฐ)๋กœ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.
โ€ข
๋ณดํ†ต ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
โ—ฆ
head: ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ๋…ธ๋“œ
โ—ฆ
(์„ ํƒ) tail: ๋ฆฌ์ŠคํŠธ์˜ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ(์ถ”๊ฐ€ ์—ฐ์‚ฐ ์ตœ์ ํ™”)

์žฅ๋‹จ์ (์‹œ๊ฐ„ ๋ณต์žก๋„)

โ€ข
์žฅ์ 
โ—ฆ
์ค‘๊ฐ„ ์‚ฝ์ž…/์‚ญ์ œ๊ฐ€ ํฌ์ธํ„ฐ ๋ณ€๊ฒฝ์œผ๋กœ ๊ฐ€๋Šฅ(๋…ธ๋“œ๋ฅผ ์ด๋ฏธ ์ฐพ์•˜๋‹ค๋Š” ์ „์ œ์—์„œ O(1))
โ—ฆ
ํฌ๊ธฐ ๋ณ€๊ฒฝ์ด ์ž์œ ๋กœ์›€(ํ•„์š”ํ•œ ๋งŒํผ ๋…ธ๋“œ๋ฅผ ๋™์  ์ƒ์„ฑ)
โ€ข
๋‹จ์ 
โ—ฆ
์ธ๋ฑ์Šค ์ ‘๊ทผ ๋ถˆ๊ฐ€ โ†’ k๋ฒˆ์งธ ์ ‘๊ทผ์€ ์ˆœ์ฐจ ํƒ์ƒ‰ O(n)
โ—ฆ
๋…ธ๋“œ๋งˆ๋‹ค ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•˜๋ฏ€๋กœ ์ถ”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฒ„ํ—ค๋“œ ์กด์žฌ
์ž์ฃผ ์“ฐ๋Š” ์—ฐ์‚ฐ์˜ ํ‰๊ท ์  ๋น„์šฉ(๋‹จ์ˆœ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ):
โ€ข
๋งจ ์•ž ์‚ฝ์ž…(pushFront): O(1)
โ€ข
๋งจ ์•ž ์‚ญ์ œ(popFront): O(1)
โ€ข
ํƒ์ƒ‰(search): O(n)
โ€ข
๋งจ ๋’ค ์‚ฝ์ž…(pushBack): tail ์ด ์žˆ์œผ๋ฉด O(1), ์—†์œผ๋ฉด O(n)

Java๋กœ ์ง์ ‘ ๊ตฌํ˜„ ์˜ˆ์‹œ

public class SinglyLinkedList<E> { private static class Node<E> { E data; Node<E> next; Node(E data) { this.data = data; } } private Node<E> head; private Node<E> tail; // ์—†์• ๋„ ๋˜์ง€๋งŒ, ์žˆ์œผ๋ฉด ๋งจ ๋’ค ์ถ”๊ฐ€๊ฐ€ ๋นจ๋ผ์ง private int size; public int size() { return size; } public boolean isEmpty() { return size == 0; } // ๋งจ ์•ž์— ์‚ฝ์ž… public void addFirst(E value) { Node<E> node = new Node<>(value); node.next = head; head = node; if (tail == null) tail = head; size++; } // ๋งจ ๋’ค์— ์‚ฝ์ž… public void addLast(E value) { Node<E> node = new Node<>(value); if (head == null) { head = tail = node; } else { tail.next = node; tail = node; } size++; } // ์ฒซ ์›์†Œ ์‚ญ์ œ ํ›„ ๋ฐ˜ํ™˜ public E removeFirst() { if (head == null) throw new IllegalStateException("empty"); E val = head.data; head = head.next; if (head == null) tail = null; size--; return val; } // value๊ฐ€ ์žˆ๋Š”์ง€ ์ˆœ์ฐจ ํƒ์ƒ‰ public boolean contains(E value) { for (Node<E> cur = head; cur != null; cur = cur.next) { if ((value == null && cur.data == null) || (value != null && value.equals(cur.data))) return true; } return false; } }
Java
๋ณต์‚ฌ

Mermaid๋กœ โ€œ๋…ธ๋“œ(ํฌ์ธํ„ฐ)โ€ ํ‘œํ˜„ํ•˜๊ธฐ

Mermaid์—์„œ๋Š” ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณดํ†ต ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„ ๋กœ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.
โ€ข
๋…ธ๋“œ: ์‚ฌ๊ฐํ˜•(๋˜๋Š” ์›ํ•˜๋Š” ๋ชจ์–‘)
โ€ข
next ํฌ์ธํ„ฐ: ํ™”์‚ดํ‘œ -->
โ€ข
null: ์ข…๋‹จ ๋…ธ๋“œ๋ฅผ null ๋กœ ์—ฐ๊ฒฐํ•ด์„œ ๋์„ ํ‘œํ˜„

์˜ˆ์‹œ 1) ๊ธฐ๋ณธ ์—ฐ๊ฒฐ

flowchart LR
    head((head)) --> n1["Node 1<br>data: 10"]
    n1 --> n2["Node 2<br>data: 20"]
    n2 --> n3["Node 3<br>data: 30"]
    n3 --> null((null))
Mermaid
๋ณต์‚ฌ

์˜ˆ์‹œ 2) head๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” โ€œ์ฐธ์กฐ(๋ณ€์ˆ˜)โ€๊นŒ์ง€ ๋ช…์‹œ

flowchart LR
    headRef["head"] --> n1["data: A"]
    n1 -- next --> n2["data: B"]
    n2 -- next --> n3["data: C"]
    n3 -- next --> null((null))
Mermaid
๋ณต์‚ฌ

์˜ˆ์‹œ 3) tail์„ ํ•จ๊ป˜ ํ‘œํ˜„(์„ ํƒ)

flowchart LR
    headRef["head"] --> n1["data: 1"]
    n1 --> n2["data: 2"]
    n2 --> n3["data: 3"]
    tailRef["tail"] --> n3
    n3 --> null((null))
Mermaid
๋ณต์‚ฌ
ํŒ:
โ€ข
๋…ธ๋“œ ์•ˆ์—์„œ ์ค„๋ฐ”๊ฟˆ์€ \n ๋Œ€์‹  ๋ฅผ ์“ฐ๋ฉด ์•ˆ์ •์ ์œผ๋กœ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค.
โ€ข
์—ฐ๊ฒฐ ๋ฐฉํ–ฅ์„ ์™ผโ†’์˜ค๋กœ ๋ณด๋ ค๋ฉด flowchart LR, ์œ„โ†’์•„๋ž˜๋ฉด flowchart TD ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.