๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Knowledge/Data structure

[์ž๋ฃŒ๊ตฌ์กฐ]ํŒŒ์ด์ฌ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ์ž๋ฃŒ๊ตฌ์กฐ ์™„๋ฒฝ ๊ฐ€์ด๋“œ: ๊ธฐ์ดˆ๋ถ€ํ„ฐ ํ™œ์šฉ๊นŒ์ง€

by YJ Dev 2024. 7. 22.
728x90
๋ฐ˜์‘ํ˜•
SMALL

ํŒŒ์ด์ฌ์—์„œ ๋ฐฐ์—ด์€ ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€๋งŒ, ๋” ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ํ•„์š”๋กœ ํ•  ๋•Œ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๋ฐ์ดํ„ฐ์˜ ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ์‚ฝ์ž…๊ณผ ์‚ญ์ œ๊ฐ€ ์šฉ์ดํ•œ ์ž๋ฃŒ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ์ด ํฌ์ŠคํŒ…์—์„œ๋Š” ํŒŒ์ด์ฌ์œผ๋กœ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์„ค๋ช…ํ•˜๊ณ , ๊ทธ ํ™œ์šฉ๋ฒ•์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ์ž๋ฃŒ๊ตฌ์กฐ ํŒŒ์ด์ฌ


01. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๊ธฐ๋ณธ ๊ฐœ๋…๐Ÿ“˜

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๊ฐ ๋…ธ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ์™€ ๋‹ค์Œ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ๋ฐฐ์—ด๊ณผ ๋‹ฌ๋ฆฌ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์—ฐ์†์ ์œผ๋กœ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์–ด ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ์ฃผ์š” ํŠน์ง•

  1. ๋™์  ํฌ๊ธฐ: ๋ฐฐ์—ด์€ ๊ณ ์ • ํฌ๊ธฐ์ง€๋งŒ, ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ๋•Œ๋งˆ๋‹ค ํฌ๊ธฐ๊ฐ€ ๋™์ ์œผ๋กœ ๋ณ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์˜ ํšจ์œจ์„ฑ: ํ•„์š”ํ•œ ๋งŒํผ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๊ฐ€ ์ ์Šต๋‹ˆ๋‹ค.
  3. ์‚ฝ์ž… ๋ฐ ์‚ญ์ œ๊ฐ€ ์šฉ์ด: ํŠน์ • ์œ„์น˜์— ์š”์†Œ๋ฅผ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ์ž‘์—…์ด ๋ฐฐ์—ด๋ณด๋‹ค ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. ๋ฐฐ์—ด์—์„œ๋Š” ์‚ฝ์ž… ๋˜๋Š” ์‚ญ์ œ ํ›„ ์š”์†Œ๋“ค์„ ์ด๋™์‹œ์ผœ์•ผ ํ•˜์ง€๋งŒ, ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ๋Š” ์ฐธ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๊ตฌ์„ฑ ์š”์†Œ

  1. ๋…ธ๋“œ(Node): ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๊ธฐ๋ณธ ๋‹จ์œ„๋กœ, ๋ฐ์ดํ„ฐ์™€ ๋‹ค์Œ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
    - ๋ฐ์ดํ„ฐ: ๋…ธ๋“œ๊ฐ€ ์ €์žฅํ•˜๋Š” ์‹ค์ œ ๊ฐ’.
    - ํฌ์ธํ„ฐ: ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฐธ์กฐ.
  2. ํ—ค๋“œ ํฌ์ธํ„ฐ(Head Pointer): ๋ฆฌ์ŠคํŠธ์˜ ์‹œ์ž‘์ ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋กœ, ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ์ข…๋ฅ˜

  1. ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Singly Linked List): ๊ฐ ๋…ธ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.
    ๊ตฌ์„ฑ: ๋…ธ๋“œ(Node)์™€ ํฌ์ธํ„ฐ(Next)๋กœ ๊ตฌ์„ฑ.
  2. ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Doubly Linked List): ๊ฐ ๋…ธ๋“œ๊ฐ€ ๋‘ ๊ฐœ์˜ ํฌ์ธํ„ฐ(ํ•˜๋‚˜๋Š” ๋‹ค์Œ ๋…ธ๋“œ, ํ•˜๋‚˜๋Š” ์ด์ „ ๋…ธ๋“œ)๋ฅผ ๊ฐ€์ง€๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.
    ๊ตฌ์„ฑ: ๋…ธ๋“œ(Node), ๋‹ค์Œ ๋…ธ๋“œ ํฌ์ธํ„ฐ(Next), ์ด์ „ ๋…ธ๋“œ ํฌ์ธํ„ฐ(Prev).
  3. ํ™˜ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Circular Linked List): ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌ์ผœ ์›ํ˜•์œผ๋กœ ์—ฐ๊ฒฐ๋œ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.
    - ๋‹จ์ผ ํ™˜ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ: ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋ณ€ํ˜•์œผ๋กœ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ์˜ ๋‹ค์Œ ํฌ์ธํ„ฐ๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
    - ์ด์ค‘ ํ™˜ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ: ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋ณ€ํ˜•์œผ๋กœ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ์˜ ๋‹ค์Œ ํฌ์ธํ„ฐ๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ , ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ์˜ ์ด์ „ ํฌ์ธํ„ฐ๊ฐ€ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๊ธฐ๋ณธ ์—ฐ์‚ฐ

  1. ์‚ฝ์ž…(Insertion): ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ๋ฆฌ์ŠคํŠธ์˜ ํŠน์ • ์œ„์น˜์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  2. ์‚ญ์ œ(Deletion): ๋ฆฌ์ŠคํŠธ์—์„œ ํŠน์ • ๋…ธ๋“œ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
  3. ํƒ์ƒ‰(Search): ๋ฆฌ์ŠคํŠธ์—์„œ ํŠน์ • ๊ฐ’์„ ์ฐพ์Šต๋‹ˆ๋‹ค.
  4. ์ˆœํšŒ(Traversal): ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•ฉ๋‹ˆ๋‹ค.

02. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ ๊ตฌํ˜„๐Ÿ› ๏ธ

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์˜ ๊ธฐ๋ณธ ๋‹จ์œ„๋กœ, ๋‹ค์Œ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ฐธ์กฐ(ํฌ์ธํ„ฐ)์™€ ํ•จ๊ป˜ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. Python์—์„œ๋Š” ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์™€ ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ ๊ตฌํ˜„ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ ๊ตฌํ˜„

๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ๋Š” ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ(next)์™€ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

class Node:
    def __init__(self, data):
        self.data = data  # ๋…ธ๋“œ๊ฐ€ ์ €์žฅํ•  ๋ฐ์ดํ„ฐ
        self.next = None  # ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ

# ๋…ธ๋“œ ์ƒ์„ฑ ์˜ˆ์‹œ
node1 = Node(1)
node2 = Node(2)
node1.next = node2  # node1์ด node2๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์„ค์ •

print(node1.data)  # Output: 1
print(node1.next.data)  # Output: 2

์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ ๊ตฌํ˜„

์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ๋Š” ์ด์ „ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ(prev)์™€ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ(next), ๊ทธ๋ฆฌ๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

class DoublyNode:
    def __init__(self, data):
        self.data = data  # ๋…ธ๋“œ๊ฐ€ ์ €์žฅํ•  ๋ฐ์ดํ„ฐ
        self.prev = None  # ์ด์ „ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ
        self.next = None  # ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ

# ๋…ธ๋“œ ์ƒ์„ฑ ์˜ˆ์‹œ
dnode1 = DoublyNode(1)
dnode2 = DoublyNode(2)
dnode1.next = dnode2  # dnode1์ด dnode2๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์„ค์ •
dnode2.prev = dnode1  # dnode2๊ฐ€ dnode1์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์„ค์ •

print(dnode1.data)  # Output: 1
print(dnode1.next.data)  # Output: 2
print(dnode2.prev.data)  # Output: 1

๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์™€ ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋น„๊ต

  • ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ: ๊ฐ ๋…ธ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ๋‹ค์Œ ๋…ธ๋“œ์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฝ์ž…๊ณผ ์‚ญ์ œ ์—ฐ์‚ฐ์ด ๊ฐ„๋‹จํ•˜์ง€๋งŒ, ๋‹จ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ: ๊ฐ ๋…ธ๋“œ๊ฐ€ ์ด์ „ ๋…ธ๋“œ์™€ ๋‹ค์Œ ๋…ธ๋“œ์— ๋Œ€ํ•œ ๋‘ ๊ฐœ์˜ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์–‘๋ฐฉํ–ฅ์œผ๋กœ ํƒ์ƒ‰์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์‚ฝ์ž…๊ณผ ์‚ญ์ œ ์—ฐ์‚ฐ์ด ๋” ์œ ์—ฐํ•˜์ง€๋งŒ, ์ถ”๊ฐ€์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

03. ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๊ตฌํ˜„๐Ÿ’ก

๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Singly Linked List)๋Š” ๊ฐ ๋…ธ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ๋‹ค์Œ ๋…ธ๋“œ์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ์ด ๊ตฌ์กฐ๋ฅผ Python ํด๋ž˜์Šค๋กœ ๊ตฌํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌํ˜„์—๋Š” ์‚ฝ์ž…, ์‚ญ์ œ, ํƒ์ƒ‰, ์ˆœํšŒ ๋“ฑ์˜ ๊ธฐ๋ณธ ์—ฐ์‚ฐ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
class Node:
    def __init__(self, data):
        self.data = data  # ๋…ธ๋“œ๊ฐ€ ์ €์žฅํ•  ๋ฐ์ดํ„ฐ
        self.next = None  # ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ

class SinglyLinkedList:
    def __init__(self):
        self.head = None  # ๋ฆฌ์ŠคํŠธ์˜ ์‹œ์ž‘์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ

    def insert(self, data):
        """๋ฆฌ์ŠคํŠธ์˜ ๋งจ ์•ž์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค."""
        new_node = Node(data)
        new_node.next = self.head
        self.head = new_node

    def delete(self, key):
        """๋ฆฌ์ŠคํŠธ์—์„œ ์ฃผ์–ด์ง„ ๊ฐ’์„ ๊ฐ€์ง„ ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค."""
        temp = self.head

        if temp is not None:
            if temp.data == key:
                self.head = temp.next
                temp = None
                return

        while temp is not None:
            if temp.data == key:
                break
            prev = temp
            temp = temp.next

        if temp == None:
            return

        prev.next = temp.next
        temp = None

    def search(self, key):
        """๋ฆฌ์ŠคํŠธ์—์„œ ์ฃผ์–ด์ง„ ๊ฐ’์„ ๊ฐ€์ง„ ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค."""
        current = self.head
        while current is not None:
            if current.data == key:
                return True
            current = current.next
        return False

    def traverse(self):
        """๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•ฉ๋‹ˆ๋‹ค."""
        current = self.head
        while current:
            print(current.data, end=" -> ")
            current = current.next
        print("None")

# ์‚ฌ์šฉ ์˜ˆ์‹œ
sll = SinglyLinkedList()
sll.insert(1)
sll.insert(2)
sll.insert(3)
sll.traverse()  # Output: 3 -> 2 -> 1 -> None
sll.delete(2)
sll.traverse()  # Output: 3 -> 1 -> None
print(sll.search(1))  # Output: True
print(sll.search(4))  # Output: False

์ฝ”๋“œ ์„ค๋ช…

Node ํด๋ž˜์Šค:

  • __init__ ๋ฉ”์„œ๋“œ๋Š” ๋…ธ๋“œ๊ฐ€ ์ €์žฅํ•  ๋ฐ์ดํ„ฐ(data)์™€ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ(next)๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

SinglyLinkedList ํด๋ž˜์Šค:

  • __init__ ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์‹œ์ž‘์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ(head)๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • insert ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋งจ ์•ž์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋…ธ๋“œ์˜ next ํฌ์ธํ„ฐ๋Š” ํ˜„์žฌ์˜ head๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฉฐ, head๋Š” ์ƒˆ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.
  • delete ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์—์„œ ์ฃผ์–ด์ง„ ๊ฐ’์„ ๊ฐ€์ง„ ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. head๊ฐ€ ์‚ญ์ œ๋  ๋…ธ๋“œ์ธ์ง€ ํ™•์ธํ•œ ํ›„, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์‚ญ์ œํ•  ๋…ธ๋“œ๋ฅผ ์ฐพ๊ณ , ์ด์ „ ๋…ธ๋“œ์˜ next ํฌ์ธํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
  • search ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ฃผ์–ด์ง„ ๊ฐ’์„ ๊ฐ€์ง„ ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ๊ฐ’์„ ์ฐพ์œผ๋ฉด True๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด False๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • traverse ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋“œ๊ฐ€ ๋๋‚˜๋ฉด None์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

04. ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๊ตฌํ˜„๐Ÿ”„

์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Doubly Linked List)๋Š” ๊ฐ ๋…ธ๋“œ๊ฐ€ ์ด์ „ ๋…ธ๋“œ์™€ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋‘ ๊ฐœ์˜ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ์ด ๊ตฌ์กฐ๋ฅผ Python ํด๋ž˜์Šค๋กœ ๊ตฌํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ตฌํ˜„์—๋Š” ์‚ฝ์ž…, ์‚ญ์ œ, ํƒ์ƒ‰, ์ˆœํšŒ ๋“ฑ์˜ ๊ธฐ๋ณธ ์—ฐ์‚ฐ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

class DoublyNode:
    def __init__(self, data):
        self.data = data  # ๋…ธ๋“œ๊ฐ€ ์ €์žฅํ•  ๋ฐ์ดํ„ฐ
        self.prev = None  # ์ด์ „ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ
        self.next = None  # ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ

class DoublyLinkedList:
    def __init__(self):
        self.head = None  # ๋ฆฌ์ŠคํŠธ์˜ ์‹œ์ž‘์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ

    def insert_front(self, data):
        """๋ฆฌ์ŠคํŠธ์˜ ๋งจ ์•ž์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค."""
        new_node = DoublyNode(data)
        new_node.next = self.head
        if self.head is not None:
            self.head.prev = new_node
        self.head = new_node

    def insert_end(self, data):
        """๋ฆฌ์ŠคํŠธ์˜ ๋งจ ๋์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค."""
        new_node = DoublyNode(data)
        if self.head is None:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node
        new_node.prev = last

    def delete_node(self, node):
        """์ฃผ์–ด์ง„ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค."""
        if self.head is None or node is None:
            return

        if self.head == node:
            self.head = node.next

        if node.next is not None:
            node.next.prev = node.prev

        if node.prev is not None:
            node.prev.next = node.next

        node = None

    def search(self, key):
        """๋ฆฌ์ŠคํŠธ์—์„œ ์ฃผ์–ด์ง„ ๊ฐ’์„ ๊ฐ€์ง„ ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค."""
        current = self.head
        while current is not None:
            if current.data == key:
                return True
            current = current.next
        return False

    def traverse_forward(self):
        """๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•ฉ๋‹ˆ๋‹ค (์ •๋ฐฉํ–ฅ)."""
        current = self.head
        while current:
            print(current.data, end=" <-> ")
            current = current.next
        print("None")

    def traverse_backward(self):
        """๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•ฉ๋‹ˆ๋‹ค (์—ญ๋ฐฉํ–ฅ)."""
        current = self.head
        last = None
        while current:
            last = current
            current = current.next

        while last:
            print(last.data, end=" <-> ")
            last = last.prev
        print("None")

# ์‚ฌ์šฉ ์˜ˆ์‹œ
dll = DoublyLinkedList()
dll.insert_front(1)
dll.insert_front(2)
dll.insert_end(3)
dll.traverse_forward()  # Output: 2 <-> 1 <-> 3 <-> None
dll.traverse_backward() # Output: 3 <-> 1 <-> 2 <-> None
dll.delete_node(dll.head.next)  # ๋…ธ๋“œ 1์„ ์‚ญ์ œ
dll.traverse_forward()  # Output: 2 <-> 3 <-> None
print(dll.search(2))  # Output: True
print(dll.search(4))  # Output: False

์ฝ”๋“œ ์„ค๋ช…

DoublyNode ํด๋ž˜์Šค:

  • __init__ ๋ฉ”์„œ๋“œ๋Š” ๋…ธ๋“œ๊ฐ€ ์ €์žฅํ•  ๋ฐ์ดํ„ฐ(data), ์ด์ „ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ(prev), ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ(next)๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

DoublyLinkedList ํด๋ž˜์Šค:

  • __init__ ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์‹œ์ž‘์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ(head)๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • insert_front ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋งจ ์•ž์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋…ธ๋“œ์˜ next ํฌ์ธํ„ฐ๋Š” ํ˜„์žฌ์˜ head๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฉฐ, head๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋…ธ๋“œ์˜ prev ํฌ์ธํ„ฐ๋Š” ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  head๋Š” ์ƒˆ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.
  • insert_end ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋งจ ๋์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด head๊ฐ€ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฆฌ์ŠคํŠธ์˜ ๋๊นŒ์ง€ ์ด๋™ํ•˜์—ฌ ์ƒˆ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • delete_node ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์—์„œ ์ฃผ์–ด์ง„ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ์‚ญ์ œํ•  ๋…ธ๋“œ๊ฐ€ head์ธ์ง€, ์ค‘๊ฐ„์— ์žˆ๋Š”์ง€, ๋์— ์žˆ๋Š”์ง€์— ๋”ฐ๋ผ ํฌ์ธํ„ฐ๋ฅผ ์ ์ ˆํžˆ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
  • search ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ฃผ์–ด์ง„ ๊ฐ’์„ ๊ฐ€์ง„ ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ๊ฐ’์„ ์ฐพ์œผ๋ฉด True๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด False๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • traverse_forward ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ •๋ฐฉํ–ฅ์œผ๋กœ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋“œ๊ฐ€ ๋๋‚˜๋ฉด None์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • traverse_backward ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์—ญ๋ฐฉํ–ฅ์œผ๋กœ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋“œ๊ฐ€ ๋๋‚˜๋ฉด None์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

05. ์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๊ตฌํ˜„๐Ÿ”

์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Circular Linked List)๋Š” ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌ์กฐ๋Š” ๋‹จ์ผ ๋˜๋Š” ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๋‹จ์ผ ์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌํ˜„์—๋Š” ์‚ฝ์ž…, ์‚ญ์ œ, ํƒ์ƒ‰, ์ˆœํšŒ ๋“ฑ์˜ ๊ธฐ๋ณธ ์—ฐ์‚ฐ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

class Node:
    def __init__(self, data):
        self.data = data  # ๋…ธ๋“œ๊ฐ€ ์ €์žฅํ•  ๋ฐ์ดํ„ฐ
        self.next = None  # ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ

class CircularLinkedList:
    def __init__(self):
        self.head = None  # ๋ฆฌ์ŠคํŠธ์˜ ์‹œ์ž‘์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ

    def insert_front(self, data):
        """๋ฆฌ์ŠคํŠธ์˜ ๋งจ ์•ž์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค."""
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            self.head.next = self.head
        else:
            temp = self.head
            while temp.next != self.head:
                temp = temp.next
            new_node.next = self.head
            temp.next = new_node
            self.head = new_node

    def insert_end(self, data):
        """๋ฆฌ์ŠคํŠธ์˜ ๋งจ ๋์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค."""
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            self.head.next = self.head
        else:
            temp = self.head
            while temp.next != self.head:
                temp = temp.next
            temp.next = new_node
            new_node.next = self.head

    def delete_node(self, key):
        """๋ฆฌ์ŠคํŠธ์—์„œ ์ฃผ์–ด์ง„ ๊ฐ’์„ ๊ฐ€์ง„ ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค."""
        if self.head is None:
            return
        
        temp = self.head
        prev = None

        # ๋ฆฌ์ŠคํŠธ์— ๋…ธ๋“œ๊ฐ€ ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ
        if temp.data == key and temp.next == self.head:
            self.head = None
            return

        # ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒฝ์šฐ
        if temp.data == key:
            while temp.next != self.head:
                temp = temp.next
            temp.next = self.head.next
            self.head = self.head.next
            return

        # ๋ฆฌ์ŠคํŠธ์˜ ์ค‘๊ฐ„ ๋˜๋Š” ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒฝ์šฐ
        while temp.next != self.head:
            prev = temp
            temp = temp.next
            if temp.data == key:
                prev.next = temp.next
                return

    def search(self, key):
        """๋ฆฌ์ŠคํŠธ์—์„œ ์ฃผ์–ด์ง„ ๊ฐ’์„ ๊ฐ€์ง„ ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค."""
        if self.head is None:
            return False
        
        temp = self.head
        while True:
            if temp.data == key:
                return True
            temp = temp.next
            if temp == self.head:
                break
        return False

    def traverse(self):
        """๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•ฉ๋‹ˆ๋‹ค."""
        if self.head is None:
            print("List is empty")
            return
        
        temp = self.head
        while True:
            print(temp.data, end=" -> ")
            temp = temp.next
            if temp == self.head:
                break
        print("HEAD")

# ์‚ฌ์šฉ ์˜ˆ์‹œ
cll = CircularLinkedList()
cll.insert_front(1)
cll.insert_front(2)
cll.insert_end(3)
cll.traverse()  # Output: 2 -> 1 -> 3 -> HEAD
cll.delete_node(1)
cll.traverse()  # Output: 2 -> 3 -> HEAD
print(cll.search(2))  # Output: True
print(cll.search(4))  # Output: False

์ฝ”๋“œ ์„ค๋ช…

Node ํด๋ž˜์Šค:

  • __init__ ๋ฉ”์„œ๋“œ๋Š” ๋…ธ๋“œ๊ฐ€ ์ €์žฅํ•  ๋ฐ์ดํ„ฐ(data)์™€ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ(next)๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

CircularLinkedList ํด๋ž˜์Šค:

  • __init__ ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์‹œ์ž‘์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ(head)๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • insert_front ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋งจ ์•ž์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด ์ƒˆ ๋…ธ๋“œ์˜ next ํฌ์ธํ„ฐ๋Š” ์ž๊ธฐ ์ž์‹ ์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜์—ฌ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ณ , ์ƒˆ ๋…ธ๋“œ๋ฅผ head๋กœ ์„ค์ •ํ•˜๋ฉฐ, ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ์˜ next ํฌ์ธํ„ฐ๋ฅผ ์ƒˆ ๋…ธ๋“œ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • insert_end ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋งจ ๋์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด ์ƒˆ ๋…ธ๋“œ์˜ next ํฌ์ธํ„ฐ๋Š” ์ž๊ธฐ ์ž์‹ ์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜์—ฌ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ณ , ์ƒˆ ๋…ธ๋“œ๋ฅผ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ์˜ next ํฌ์ธํ„ฐ์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
  • delete_node ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์—์„œ ์ฃผ์–ด์ง„ ๊ฐ’์„ ๊ฐ€์ง„ ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ์‚ญ์ œํ•  ๋…ธ๋“œ๊ฐ€ head์ธ์ง€, ์ค‘๊ฐ„์— ์žˆ๋Š”์ง€, ๋์— ์žˆ๋Š”์ง€์— ๋”ฐ๋ผ ํฌ์ธํ„ฐ๋ฅผ ์ ์ ˆํžˆ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
  • search ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ฃผ์–ด์ง„ ๊ฐ’์„ ๊ฐ€์ง„ ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ๊ฐ’์„ ์ฐพ์œผ๋ฉด True๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด False๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • traverse ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์—๋Š” HEAD๋ฅผ ์ถœ๋ ฅํ•˜์—ฌ ์›ํ˜• ๋ฆฌ์ŠคํŠธ์˜ ๋์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

06. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์™€ ๊ด€๋ จ๋œ ๋ฌธ์ œ ํ•ด๊ฒฐ๐Ÿ”

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ ์ค‘๋ณต ์ œ๊ฑฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

  • ๋ฐฉ๋ฒ• 1: set์„ ์‚ฌ์šฉํ•˜์—ฌ O(n) ์‹œ๊ฐ„ ๋ณต์žก๋„๋กœ ์ค‘๋ณต์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ๋…ธ๋“œ๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ์ด๋ฏธ ๋“ฑ์žฅํ•œ ๊ฐ’์„ set์— ์ €์žฅํ•˜๊ณ , ๋‹ค์Œ์— ๋™์ผํ•œ ๊ฐ’์ด ๋“ฑ์žฅํ•˜๋ฉด ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐฉ๋ฒ• 2: ๋‘ ๊ฐœ์˜ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋น„๊ตํ•˜๋ฉฐ ์ค‘๋ณต์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์ถ”๊ฐ€์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ์—†์ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Python ์ฝ”๋“œ (๋ฐฉ๋ฒ• 1, set ์‚ฌ์šฉ):

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class SinglyLinkedList:
    def __init__(self):
        self.head = None

    def insert_end(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node

    def remove_duplicates(self):
        seen = set()
        current = self.head
        prev = None
        while current:
            if current.data in seen:
                prev.next = current.next
            else:
                seen.add(current.data)
                prev = current
            current = current.next

    def traverse(self):
        current = self.head
        while current:
            print(current.data, end=" -> ")
            current = current.next
        print("None")

# ์‚ฌ์šฉ ์˜ˆ์‹œ
sll = SinglyLinkedList()
sll.insert_end(1)
sll.insert_end(2)
sll.insert_end(2)
sll.insert_end(3)
sll.insert_end(3)
sll.traverse()  # Output: 1 -> 2 -> 2 -> 3 -> 3 -> None
sll.remove_duplicates()
sll.traverse()  # Output: 1 -> 2 -> 3 -> None

Python ์ฝ”๋“œ (๋ฐฉ๋ฒ• 2, ๋‘ ํฌ์ธํ„ฐ ์‚ฌ์šฉ):

class SinglyLinkedList:
    def __init__(self):
        self.head = None

    def insert_end(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node

    def remove_duplicates(self):
        current = self.head
        while current:
            runner = current
            while runner.next:
                if runner.next.data == current.data:
                    runner.next = runner.next.next
                else:
                    runner = runner.next
            current = current.next

    def traverse(self):
        current = self.head
        while current:
            print(current.data, end=" -> ")
            current = current.next
        print("None")

# ์‚ฌ์šฉ ์˜ˆ์‹œ
sll = SinglyLinkedList()
sll.insert_end(1)
sll.insert_end(2)
sll.insert_end(2)
sll.insert_end(3)
sll.insert_end(3)
sll.traverse()  # Output: 1 -> 2 -> 2 -> 3 -> 3 -> None
sll.remove_duplicates()
sll.traverse()  # Output: 1 -> 2 -> 3 -> None

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๊ธธ์ด ๊ตฌํ•˜๊ธฐ:

 

๋ฌธ์ œ: ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด๋ฅผ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•: ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜๋ฅผ ์นด์šดํŠธํ•ฉ๋‹ˆ๋‹ค.

Python ์ฝ”๋“œ:

class SinglyLinkedList:
    def __init__(self):
        self.head = None

    def insert_end(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node

    def length(self):
        count = 0
        current = self.head
        while current:
            count += 1
            current = current.next
        return count

    def traverse(self):
        current = self.head
        while current:
            print(current.data, end=" -> ")
            current = current.next
        print("None")

# ์‚ฌ์šฉ ์˜ˆ์‹œ
sll = SinglyLinkedList()
sll.insert_end(1)
sll.insert_end(2)
sll.insert_end(3)
print(sll.length())  # Output: 3

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ ํŠน์ • ๊ฐ’ ์ฐพ๊ธฐ:

 

๋ฌธ์ œ: ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ ํŠน์ • ๊ฐ’์„ ๊ฐ€์ง„ ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•: ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ๊ฐ ๋…ธ๋“œ์˜ ๊ฐ’์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

Python ์ฝ”๋“œ:

class SinglyLinkedList:
    def __init__(self):
        self.head = None

    def insert_end(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node

    def search(self, key):
        current = self.head
        while current:
            if current.data == key:
                return True
            current = current.next
        return False

    def traverse(self):
        current = self.head
        while current:
            print(current.data, end=" -> ")
            current = current.next
        print("None")

# ์‚ฌ์šฉ ์˜ˆ์‹œ
sll = SinglyLinkedList()
sll.insert_end(1)
sll.insert_end(2)
sll.insert_end(3)
print(sll.search(2))  # Output: True
print(sll.search(4))  # Output: False

 

728x90
๋ฐ˜์‘ํ˜•