Algorithm/๐ Concept
[์๋ฃ๊ตฌ์กฐ] ๋จ์/์ํ/์ด์ค ์ฐ๊ฒฐ๋ฆฌ์คํธ(Linked List) ๊ตฌํ - ํ์ด์ฌ(Python)
J1Yun
2023. 3. 7. 18:12
728x90
์ฐ๊ฒฐ๋ฆฌ์คํธ(Linked List)
- ๋ค์ ์์์ ์๋ฃ๊ฐ ์๋ ์์น๋ฅผ ๋ฐ์ดํฐ์ ํฌํจ์ํค๋ ๋ฐฉ์์ผ๋ก ์๋ฃ๋ฅผ ์ ์ฅํ๋ ์ ํ ์๋ฃ๊ตฌ์กฐ
- ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ Node๋ก ๊ตฌ์ฑ๋์ด ์๊ณ , Node ์์๋ Data์ Link(Next)๋ก ๊ตฌ์ฑ
- Data: ๋ฐ์ดํฐ ๊ฐ ์ ์ฅ
- Link(Next): ๋ค์ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํด
์ฅ์
- ๋ฐ์ดํฐ ์ถ๊ฐ, ์ญ์ ์ ์ ๋ฆฌ
- ๋ฐฐ์ด: ์๊ฐ๋ณต์ก๋ O(n)
- ์ฐ๊ฒฐ๋ฆฌ์คํธ: ์๊ฐ๋ณต์ก๋ O(1)
- ๊ณต๊ฐ๋ณต์ก๋ ์ธก๋ฉด์์ ์ ๋ฆฌ (๋ฐฐ์ด์ฒ๋ผ ์ฐ์๋ ๊ณต๊ฐ์ ํ ๋นํ์ง ์๊ณ ํ์ ์์๋ง ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋์ ํ ๋นํ๊ธฐ ๋๋ฌธ)
- ๋ฉ๋ชจ๋ฆฌ ๋์ X
- ์ ์ฐํ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
๋จ์
- ๋ฐ์ดํฐ ํ์ ์ ๋ถ๋ฆฌ (๋ฐ์ดํฐ์ ๋
ผ๋ฆฌ์ ์ ์ฅ ์์์ ๋ฌผ๋ฆฌ์ ์ ์ฅ ์์๊ฐ ์ผ์นํ์ง ์์ ์ธ๋ฑ์ค ์ ๊ทผ์ด ์๋ ์ ์ฒด๋ฅผ ์ํํด์ผ ํ๊ธฐ ๋๋ฌธ)
- ๋ฐฐ์ด: ์๊ฐ๋ณต์ก๋ O(1)
- ์ฐ๊ฒฐ๋ฆฌ์คํธ: ์๊ฐ๋ณต์ก๋ O(n)
- ํ ์ดํฐ ์ ๋ ฌ ์ ๋ถ๋ฆฌ
๋จ์ ์ฐ๊ฒฐ๋ฆฌ์คํธ(Singly Linked List)
- ๊ฐ์ฅ ๋จ์ํ ๋ค์ ๋ ธ๋์ ๋ํ ์ฐธ์กฐ๋ง ๊ณ ๋ คํ ํํ์ ์ฐ๊ฒฐ๋ฆฌ์คํธ
- ๋ง์ง๋ง ๋ ธ๋๋ ํญ์ NULL์ ๊ฐ๋ฆฌํด
- ํค๋ ํฌ์ธํฐ์ ์ฃผ์๋ ๋ค์ ๋ ธ๋์ ์ฃผ์๊ฐ ๋ถ์ ํํ ๋ ๋ฐ์ดํฐ ์ ์ค์ ์ํ์ด ๋์ (์์ ์ X)
1. ๋ ธ๋ ์์ฑ
class Node:
def __init__(self, val):
self.data = val
self.next = None
2. ์ฐ๊ฒฐ๋ฆฌ์คํธ ์ด๊ธฐํ
class SimplyLinkedList:
def __init__(self):
self.nodeCount = 0 # ์ฐ๊ฒฐ๋ฆฌ์คํธ ๋ด ๋
ธ๋ ์
self.head = None # ์ฒซ ๋ฒ์งธ ๋
ธ๋
self.tail = None # ๋ง์ง๋ง ๋
ธ๋
3. ๋ ธ๋ ์ฝ์
# ๋งจ ์(head)์ ๋
ธ๋ ์ฝ์
def insert_front(self, val):
new_node = Node(val)
if self.head is None: # ๋น ์ฐ๊ฒฐ๋ฆฌ์คํธ์ผ ๋
self.head = new_node
self.tail = new_node
else: # ๋น ์ฐ๊ฒฐ๋ฆฌ์คํธ๊ฐ ์๋ ๋
new_node.next = self.head
self.head = new_node
self.nodeCount += 1
# ์ค๊ฐ์ ๋
ธ๋ ์ฝ์
def insert_middle(self, target, val):
current = self.head
while current != None:
previous = current
current = current.next
if previous.data == target: # target ๊ฐ์ ๊ฐ์ง ๋
ธ๋ ๋ค์ ์ฝ์
new_node = Node(val)
new_node.next = current
previous.next = new_node
self.nodeCount += 1
break
# ๋งจ ๋(tail)์ ๋
ธ๋ ์ฝ์
def insert_back(self, val):
new_node = Node(val)
if self.head is None: # ๋น ์ฐ๊ฒฐ๋ฆฌ์คํธ์ผ ๋
self.head = new_node
self.head = new_node
else: # ๋น ์ฐ๊ฒฐ๋ฆฌ์คํธ๊ฐ ์๋ ๋
self.tail.next = new_node
self.tail = new_node
self.nodeCount += 1
4. ๋ ธ๋ ์ญ์
def delete_front(self):
# ์ฐ๊ฒฐ๋ฆฌ์คํธ๊ฐ ๋น์ด์์ง ์์ ๊ฒฝ์ฐ
current = self.head
self.head = self.head.next
del(current)
self.nodeCount -= 1
def delete_middle(self, target):
current = self.head
while current != None:
previous = current
currrent = current.next
if curren.data == target:
previous.next = current.next
del(current)
self.nodeCount -= 1
break
def delete_back(self):
# ์ฐ๊ฒฐ๋ฆฌ์คํธ๊ฐ ๋น์ด์์ง ์์ ๊ฒฝ์ฐ
previous = None
current = self.head
while current.next != None: # tail ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ ๋ฐ๋ก ์ด์ ๋
ธ๋๋ฅผ ์ฐพ์์ผํ๋ฏ๋ก ์ ์ฒด ์ํ
previous = current
currrent = current.next
previous.next = None
self.tail = previous
del(current)
self.nodeCount -= 1
์ํ ์ฐ๊ฒฐ๋ฆฌ์คํธ(Circular Linked List)
- ๋จ์ ์ฐ๊ฒฐ๋ฆฌ์คํธ์์ ๋ง์ง๋ง ๋ ธ๋๊ฐ ๋ค์ ์ฒซ ๋ฒ์งธ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ์ค์ ํ ํํ์ ์ฐ๊ฒฐ๋ฆฌ์คํธ
- NULL์ ๊ฐ๋ฆฌํค๋ ๋ ธ๋๊ฐ ์์
โป ์ํ ์ฐ๊ฒฐ๋ฆฌ์คํธ์ ๊ตฌํ ๋ฐฉ์์ ๋จ์ ์ฐ๊ฒฐ๋ฆฌ์คํธ์ ๊ทธ ์๋ฆฌ๊ฐ ๋น์ทํ๊ธฐ ๋๋ฌธ์ ์ํ ์ฐ๊ฒฐ๋ฆฌ์คํธ์ ๊ตฌํ์ ์๋ตํ๊ฒ ์.
์ด์ค ์ฐ๊ฒฐ๋ฆฌ์คํธ(Doubly Linked List)
- ๋จ์ ์ฐ๊ฒฐ๋ฆฌ์คํธ์์ ๋ค์ ๋ ธ๋ ๋ฟ๋ง ์๋๋ผ ์ด์ ๋ ธ๋์ ๋ํ ์ฐธ์กฐ๋ ๊ณ ๋ คํ ํํ์ ์ฐ๊ฒฐ๋ฆฌ์คํธ
- ๋ ธ๋์ ๋ ธ๋๊ฐ ์ํธ ์ฐ๊ฒฐ
- ์ญ์ ์ ๊ทผ ๋ฐ ํ์ ๊ฐ๋ฅ
1. ๋ ธ๋ ์์ฑ
class Node:
def __init__(self, val):
self.data = val
self.prev = None
self.next = None
2. ์ฐ๊ฒฐ๋ฆฌ์คํธ ์ด๊ธฐํ
class DoublyLinkedList:
def __init__(self):
self.head = None # ์ฒซ ๋ฒ์งธ ๋
ธ๋
self.tail = None # ๋ง์ง๋ง ๋
ธ๋
self.head.next = self.tail
self.tail.prev = self.head
3. ๋ ธ๋ ์ฝ์
# ๋งจ ์(head)์ ๋
ธ๋ ์ฝ์
def insert_front(self, val):
new_node = Node(val)
if self.head is None: # ๋น ์ฐ๊ฒฐ๋ฆฌ์คํธ์ผ ๋
self.head = new_node
self.tail = new_node
self.head.next = tail
self.tail.prev = head
else: # ๋น ์ฐ๊ฒฐ๋ฆฌ์คํธ๊ฐ ์๋ ๋
new_node.next = self.head
self.head.prev = new_node
self.head = new_node
self.nodeCount += 1
# ์ค๊ฐ์ ๋
ธ๋ ์ฝ์
def insert_middle(self, target, val):
current = self.head
while current != None:
previous = current
current = current.next
if previous.data == target: # target ๊ฐ์ ๊ฐ์ง ๋
ธ๋ ๋ค์ ์ฝ์
new_node = Node(val)
new_node.next = current
current.prev = new_node
previous.next = new_node
new_node.prev = previous
self.nodeCount += 1
break
# ๋งจ ๋(tail)์ ๋
ธ๋ ์ฝ์
def insert_back(self, val):
new_node = Node(val)
if self.head is None: # ๋น ์ฐ๊ฒฐ๋ฆฌ์คํธ์ผ ๋
self.head = new_node
self.head = new_node
self.head.next = tail
self.tail.prev = head
else: # ๋น ์ฐ๊ฒฐ๋ฆฌ์คํธ๊ฐ ์๋ ๋
self.tail.next = new_node
new_node.prev = self.tail
self.tail = new_node
self.nodeCount += 1
4. ๋ ธ๋ ์ญ์
def delete_front(self):
# ์ฐ๊ฒฐ๋ฆฌ์คํธ๊ฐ ๋น์ด์์ง ์์ ๊ฒฝ์ฐ
current = self.head
self.head = self.head.next
self.head.prev = None
del(current)
self.nodeCount -= 1
def delete_middle(self, target):
current = self.head
# target์ ์์ชฝ์ ์์นํ๋ค๊ณ ๊ฐ์ (target ๋ฐ์ดํฐ๊ฐ tail๊ณผ ๊ฐ๊น๊ฒ(๋ท์ชฝ์) ์์นํ๋ค๋ฉด ์ญ์ํ๋ก ๊ตฌํ)
while current != None:
currrent = current.next
if curren.data == target:
left = current.prev
right = current.next
left.next = right
right.prev = left
del(current)
self.nodeCount -= 1
break
def delete_back(self):
# ์ฐ๊ฒฐ๋ฆฌ์คํธ๊ฐ ๋น์ด์์ง ์์ ๊ฒฝ์ฐ
current = self.tail
self.tail = self.tail.prev
self.tail.next = None
del(current)
self.nodeCount -= 1
728x90