1. 연결리스트(Linked List)란
각 노드가 데이터와 포인터를 가지고, 각 노드의 포인터가 다음 노드를 가리키게 하여 한 줄로 연결되도록 데이터를 저장하는 자료구조이다.
가장 첫 노드는 head, 마지막 노드느 tail이라고 한다.
각 노드의 앞쪽 노드를 전임 노드 (Predecessor Node), 뒤쪽 노드를 후임 노드 (Successor Node) 라고 한다
2. 연결리스트 특징(사용하는 이유)
- 데이터를 연속적인 물리 메모리에 저장하지 않아도 된다.
- 배열은 크기가 가변적이지 않기 때문에, 지정한 크기를 넘어가게 될 경우 메모리를 재할당하고, 배열 데이터를 복사하는 작업이 일어나게 되는데 연결리스트는 이러한 작업 없이 독립된 공간에 새로운 데이터를 할당하고 연결만 해주면 된다.
- 탐색은 \(O(n)\), 시작 및 끝 지점에 데이터 삽입/추출 작업은 \(O(1)\)이 소요된다.
- 탐색을 자주 해야 할 경우에는 배열, 데이터 삽입/추출을 자주 해야 할 경우에는 연결 리스트를 사용하는 것이 유리할 것이다.
3. 연결리스트 유형
1. 단일 연결 리스트(singly linked list)
후임 노드에 대한 포인터만을 갖는 가장 단순한 연결 리스트 형태이다. 큐를 구현할 때 사용하는 방식이다.
2. 이중 연결 리스트(doubly linked list)
단일 연결 리스트는 후임 노드에 대한 포인터만을 갖는 것에 비해, 이중 연결 리스트는 전임, 후임 양 방향에 대한 포인터를 갖고 있다.
3. 환형 연결리스트(circular linked list)
단일 연결리스트에서 마지막 노드(tail)가 첫 노드(head)를 가리키는 연결리스트를 말한다.
4. 연결리스트 구현
class ListNode:
def __init__(self, data, next=None) -> None:
self.data = data
self.next = next
class SinglyLinkedList:
def __init__(self) -> None:
self.head = ListNode(None)
self.size = 0
def size(self):
return self.size
def get_node(self, idx):
if self.size == 0:
print("It's empty Linked List")
return
elif idx + 1 > self.size:
print("idx is bigger than size")
return
node = self.head
for _ in range(idx):
node = node.next
return node
def append(self, data):
if self.size == 0:
self.head = ListNode(data)
else:
node = self.get_node(self.size-1)
node.next = ListNode(data)
self.size += 1
def appendleft(self, data):
if self.size == 0:
self.head = ListNode(data)
else:
node = ListNode(data)
node.next = self.head
self.head = node
self.size += 1
def insert(self, data, idx):
if idx > self.size:
print("out of range")
return
elif idx == 0:
self.appendleft(data)
else:
node = self.get_node(idx-1)
successor = node.next
node.next = ListNode(data)
node.next.next = successor
self.size += 1
def pop(self):
out = None
if self.size == 0:
print("It's empty Linked List")
return
elif self.size == 1:
out = self.head.data
self.head = ListNode(None)
else:
node = self.get_node(self.size-2)
out = node.next.data
node.next = None
self.size -= 1
return out
def popleft(self):
if self.size == 0:
print("It's empty Linked List")
return
elif self.size == 1:
out = self.head.data
self.head = ListNode(None)
else:
node = self.head
out = node.data
self.head = node.next
self.size -= 1
return out
def delete(self, idx):
if self.size == 0:
print("It's empty Linked List")
return
elif idx >= self.size:
print("out of range")
return
elif self.size == 1:
self.popleft()
else:
node = self.get_node(idx-1)
node.next = node.next.next
self.size -= 1
return
def print(self):
node = self.head
while node:
if node.next is not None:
print(f'{node.data}->', end="")
else:
print(f'{node.data}')
node = node.next
linked_list = SinglyLinkedList()
linked_list.print()
linked_list.appendleft(2)
linked_list.print()
linked_list.append(1)
linked_list.print()
linked_list.popleft()
linked_list.print()
linked_list.insert(3,1)
linked_list.print()
linked_list.insert(2,1)
linked_list.print()
linked_list.popleft()
linked_list.print()
linked_list.pop()
linked_list.print()
'자료구조와 알고리즘 > 자료구조' 카테고리의 다른 글
[자료구조] 해시테이블 (0) | 2022.04.07 |
---|---|
[자료구조] 힙(Heap) (0) | 2022.04.02 |
[자료구조] 트리(Tree) (0) | 2022.04.02 |