๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
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
๋ฐ˜์‘ํ˜•