라떼군 이야기


5 / 14강

연결 리스트

보물찾기 쪽지마다 다음 쪽지의 위치가 적혀 있다고 생각해 보세요. 쪽지들이 나란히 놓여 있을 필요는 없습니다. 연결 리스트는 각 항목이 다음 항목을 가리키는 구조입니다.

노드와 첫 번째 항목

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

head = Node("A", Node("C"))
head.next = Node("B", head.next)

current = head
while current is not None:
    print(current.value)
    current = current.next

출력은 A, B, C입니다. class는 노드의 틀을 만들고, self.valueself.next는 각 노드가 기억할 값입니다.

삽입할 때 바뀌는 것

처음에는 A → C → None입니다. 새 노드 B가 C를 가리키게 한 다음, A가 B를 가리키게 바꾸면 A → B → C → None이 됩니다. C를 다른 메모리 칸으로 밀 필요는 없습니다.

순서가 중요합니다. 기존 다음 노드의 참조를 잃기 전에 새 노드에 연결해야 합니다. 삭제할 때는 이전 노드가 삭제 대상의 다음 노드를 가리키도록 바꿉니다.

삽입은 언제 빠를까요?

삽입할 위치의 이전 노드를 이미 알고 있다면 연결을 바꾸는 일은 O(1)입니다. 하지만 ‘다섯 번째 위치’를 먼저 찾아야 한다면 헤드부터 걸어가야 합니다. 위치 탐색은 최악에 O(n)입니다.

연결 리스트는 다음 노드를 기억할 공간도 필요합니다. 배열은 인덱스로 바로 접근하고, 연결 리스트는 연결을 따라갑니다. ‘삽입이 많으면 무조건 연결 리스트’처럼 외우기보다 위치를 어떻게 찾는지도 따져 보세요.

확인 문제

A → B → C에서 B를 지우려 합니다. A를 이미 알고 있다면 어떤 연결을 바꾸면 될까요? head만 알고 B를 값으로 찾아 지운다면 전체 비용은 늘어날까요?

해설 보기

A의 다음 참조를 C로 바꿉니다. 이 연결 변경 자체는 O(1)입니다. 값을 찾아야 한다면 노드를 순서대로 확인해야 하므로 탐색을 포함한 최악의 비용은 O(n)입니다.

제품 기획, 개발 파트너 찾으시나요? 개인, 팀, 기업 모두 환영. 문제 정의부터 출시까지 함께합니다.