2024. 1. 6. 21:52ใCS - Roadmap.sh/1. Data structures
Data structures (with python) - 4. Linked List
๐ก Arrays store elements in contiguous memory locations, resulting in easily calculable addresses for the elements stored and this allows faster access to an element at a specific index. Linked lists are less rigid in their storage structure and elements are usually not stored in contiguous locations, hence they need to be stored with additional tags giving a reference to the next element. This difference in the data storage scheme decides which data structure would be more suitable for a given situation.
๋ฐฐ์ด์ ์์๋ฅผ ์ธ์ ํ ๋ฉ๋ชจ๋ฆฌ ์์น์ ์ ์ฅํ๋ฏ๋ก ์ ์ฅ๋ ์์์ ์ฃผ์๋ฅผ ์ฝ๊ฒ ๊ณ์ฐํ ์ ์์ด ํน์ ์ธ๋ฑ์ค์ ์์์ ๋ ๋น ๋ฅด๊ฒ ์ก์ธ์คํ ์ ์์ต๋๋ค. ๋งํฌ๋ ๋ชฉ๋ก์ ์ ์ฅ ๊ตฌ์กฐ๊ฐ ๋ ์๊ฒฉํ๊ณ ์ผ๋ฐ์ ์ผ๋ก ์์๊ฐ ์ธ์ ํ ์์น์ ์ ์ฅ๋์ง ์์ผ๋ฏ๋ก ๋ค์ ์์๋ฅผ ์ฐธ์กฐํ ์ ์๋ ์ถ๊ฐ ํ๊ทธ์ ํจ๊ป ์ ์ฅํด์ผ ํฉ๋๋ค. ์ด๋ฌํ ๋ฐ์ดํฐ ์ ์ฅ ์ฒด๊ณ์ ์ฐจ์ด์ ๋ฐ๋ผ ์ฃผ์ด์ง ์ํฉ์ ๋ ์ ํฉํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๊ฐ ๊ฒฐ์ ๋ฉ๋๋ค.
์ฐ๊ฒฐ ๋ฆฌ์คํธ(Linked List)๋ ๋ฐ์ดํฐ ์์๋ค์ด ๋ฉ๋ชจ๋ฆฌ์ ์ฐ์์ ์ธ ์์น์ ์ ์ฅ๋์ง ์๊ณ ,
๊ฐ ์์(node)๊ฐ ๋ค์ ์์๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ฐฉ์์ผ๋ก ๊ตฌ์ฑ๋ ์๋ฃ๊ตฌ์กฐ ์ ๋๋ค.
Linked list์ ๊ฐ ๋ ธ๋๋ ๋ ๋ถ๋ถ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
1. ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ถ๋ถ
2. ๋ค์ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ถ๋ถ(๋งํฌ ๋๋ ํฌ์ธํฐ) ์ ๋๋ค.
Linked list ์ ํน์ง
- ๋ ธ๋๋ ๋ฉ๋ชจ๋ฆฌ์ ์ด๋ ๊ณณ์ด๋ ๋ฐฐ์น๋ ์ ์๋ค.
์ด๋ array ์ ๋์กฐ์ ์ธ ํน์ง์ผ๋ก, array์ ์์๋ค์ ์ฐ์์ ์ธ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ฐฐ์ด๋๋ค.
- ์ฝ๋์ ์ฝ์ ๊ณผ ์ญ์ ๊ฐ ์๋์ ์ผ๋ก ๊ฐ๋จํฉ๋๋ค.
์ด๋ ์ฝ์ ๋๋ ์ญ์ ํ ๋ ธ๋์ ๋งํฌ๋ง ๋ณ๊ฒฝํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ง๋ง ์ด๋ฅผ ์ํด์๋ ์ฝ์ ๋๋ ์ญ์ ํ ๋ ธ๋์ ์ด์ ๋ ธ๋๋ฅผ ์์์ผ ํฉ๋๋ค.
- ๋ฐฐ์ด๊ณผ๋ ๋ฌ๋ฆฌ linked list์ ํฌ๊ธฐ๋ ๋์ ์ผ๋ก ๋ณํ ์ ์๋ค.
In Pyhton
class Node:
def __init__(self, data):
self.data = data
self.next = None
๋ ธ๋๋ฅผ ํํํ๋ ํด๋์ค๋ฅผ ์์ฑํฉ๋๋ค.
class LinkedList:
def __init__(self):
self.head = None
def append(self, data):
if not self.head:
self.head = Node(data)
else:
current = self.head
while current.next:
current = current.next
current.next = Node(data)
def display(self):
elements = []
current_node = self.head
while current_node:
elements.append(current_node.data)
current_node = current_node.next
print(elements)
๊ทธ ํ, Linked list๋ฅผ ํํํ๋ ํด๋์ค๋ฅผ ์์ฑํ๋ค.
linked_list = LinkedList()
linked_list.append('A')
linked_list.append('B')
linked_list.append('C')
linked_list.display() # ์ถ๋ ฅ: ['A', 'B', 'C']
์ด์ ๊ฐ์ด ํ์ด์ฌ์์ Linked list๋ฅผ ๊ตฌํํ ์ ์๋ค.
์๊ณ ๋ฆฌ์ฆ ํ์ฉ
์ฃผ๋ก '๋ณํฉ ์ ๋ ฌ(merge sort)' ์ ์ฌ์ฉ๋๋ค.
๋ณํฉ ์ ๋ ฌ์ ๋ถํ ์ ๋ณต(Divide and Conquer) ์ ๋ต์ ์ด์ฉํ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก,
์์๋ค์ ๊ฐ์ฅ ์์ ๋จ์๋ก ๋ถํ ํ ํ ๋ณํฉํ๋ฉด์ ์ ๋ ฌํ๋ ๋ฐฉ์์ด๋ค.
์ด ๋, Linked list๋ ๋ถํ ๊ณผ ๋ณํฉ ๊ณผ์ ์์ ์์์ ์ฝ์ ๊ณผ ์ญ์ ๊ฐ ํจ์จ์ ์ด๋ผ๋ ์ด์ ์ ์ด๋ ค ์ด ๊ณผ์ ์ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ๋ค.
1. ๋ถํ ๋จ๊ณ์์๋ Linked list๋ฅผ ๋ฐ์ผ๋ก ๋๋๋ ์์ ์ด ์ด๋ฃจ์ด์ง๋ค.
์ด ์์ ์
๋น ๋ฅธ ํฌ์ธํฐ( ํ ๋ฒ์ ๋์นธ ์ฉ ์ด๋) a.k.a ํ ๋ผ
๋๋ฆฐ ํฌ์ธํฐ( ํ๋ฒ์ ํ ์นธ์ฉ ์ด๋) a.k.a ๊ฑฐ๋ถ์ด
์ ์ฌ์ฉํด์ ๋ฆฌ์คํธ์ ์ค๊ฐ์ ์ฐพ๊ณ , ๋ฆฌ์คํธ์ ๋ ๋ถ๋ถ์ผ๋ก ๋ถํ ํฉ๋๋ค
2. ๋ณํฉ ๋จ๊ณ์์ ๋ ๊ฐ์ ์ ๋ ฌ๋ ๋ฆฌ์คํธ๋ฅผ ํ๋์ ์ ๋ ฌ๋ ๋ฆฌ์คํธ๋ก ๋ณํฉํ๋ค.
์ด ๊ณผ์ ์์ ๋ ๋ฆฌ์คํธ์ ๋จธ๋ฆฌ๋ถํฐ ๋น๊ตํ๋ฉด์ ์์ ๊ฐ์ ์ ํํด, ์๋ก์ด ๋ฆฌ์คํธ์ ์ถ๊ฐํ๊ณ ,
์ ํ๋ ๋ ธ๋๋ฅผ ๋ค์ ๋ ธ๋๋ก ์ด๋์ํจ๋ค.
์ด ์ธ์๋
์ฒด์ด๋ (ํด์ ํ ์ด๋ธ์ ์ถฉ๋์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ค ํ๋),
LRU(Least Recnetly Used) ์บ์ ๋ฑ ์ ํ์ฉ๋๋ค.
์ฝํ ๊ณต๋ต
1. ๋ ์์ ๋ง์
๋ ๊ฐ์ Linked list ๊ฐ ์ฃผ์ด์ง๋ฉฐ,
๊ฐ list์ ๋ ธ๋๋ ์ซ์์ ๊ฐ ์๋ฆฟ์๋ฅผ ํํํ๋ค. ๋ linked list๋ฅผ ๋ํ์ฌ ์๋ก์ด Linked list๋ฅผ ์์ฑํ๋ ๋ฌธ์ ์ ๋๋ค.
๊ฐ ์๋ฆฌ์์ ์ฐ์ฐ๊ณผ ์ฌ๋ฆผ์ ์ฒ๋ฆฌํด์ผ ํ๋ฏ๋ก linked list์ ์ํ ๋ฐ ๋ ธ๋ ๊ด๋ฆฌ ๋ฅ๋ ฅ์ ํ ์คํธ.
2. ์ํ Linked list ํ๋ณ
์ฃผ์ด์ง Linked list๊ฐ ์ํํ๋์ง ( = ๋ ธ๋๊ฐ ์๊ธฐ ์์ ์ ๋ค์ ๊ฐ๋ฆฌํค๋์ง) ํ๋ณํ๋ ๋ฌธ์
์ํ์ ํ๋ณํ๊ธฐ์ํด Floyd's cycle detection algorithm์ ์ฌ์ฉํ๋ค.
์ฐธ๊ณ : https://snutiise.github.io/Floyd's-Cycle-Detection-Algorithm/
"ํ ๋ผ์ ๊ฑฐ๋ถ์ด" ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํด ์ํ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ฅผ ํ๋ณ์ ํ์ด์ฌ์์ ํด๋ณด์.
# linked list ๊ตฌํ
class Node:
def __init__(self, x):
self.val = x
self.next = None
def has_cycle(head):
if head is None:
return False
slow = head # ๊ฑฐ๋ถ์ด
fast = head # ํ ๋ผ
while fast is not None and fast.next is not None:
slow = slow.next
fast = fast.next.next
if slow == fast: # ๊ฑฐ๋ถ์ด์ ํ ๋ผ๊ฐ ๋ง๋๋ฉด ์ํ ์๋ค๊ณ ํ๋จ
return True
return False
์ ํจ์๋ ํ ๋ผ์ ๊ฑฐ๋ถ์ด๊ฐ ๊ฐ์ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํฌ ๋ ์ํ์ ๊ฐ์งํ๋ค.
ํ ๋ผ๋ ๋์นธ์ฉ, ๊ฑฐ๋ถ์ด๋ ํ ์นธ ์ฉ ์ด๋ํฉ๋๋ค.
๋ง์ฝ ์ํ์ด ์กด์ฌํ๋ค๋ฉด ํ ๋ผ๋ ๊ฒฐ๊ตญ ๊ฑฐ๋ถ์ด๋ฅผ ๋ฐ๋ผ ์ก๋๋ค. ๋ ๊ฐ์ ์ ๋ณธ๋ค.
# Linked list ์์ฑ
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = head.next # ์ํ ์์ฑ
# ์ํ ์ฌ๋ถ ํ
์คํธ
print(has_cycle(head)) # True๊ฐ ์ถ๋ ฅ๋์ด์ผ ํจ
์ ์ฝ๋์์๋ ์ํ ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ฅผ ์์ฑํ๊ณ , ์ํ ์ฌ๋ถ ํ ์คํธํ๋ค.
๋ง์ง๋ง ๋ ธ๋๊ฐ 2๋ฒ์จฐ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ์ค์ ํด ์ํ์ ๋ง๋ค์์ต๋๋ค.
๋ฐ๋ผ์ has_cycle์ True๊ฐ ๋์จ๋ค.
'CS - Roadmap.sh > 1. Data structures' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Data structures (with python) - 6. Queue (2) | 2024.01.08 |
---|---|
Data structures (with python) - 5. Stack (1) | 2024.01.07 |
Data structures (with python) - 3. Heap (0) | 2024.01.05 |
Data structures (with python) - 2. Graph - 2.4. Graph Representation (1) | 2024.01.04 |
Data structures (with python) - 2. Graph - 2.3. Spanning Tree (1) | 2024.01.03 |