Menu
Coddy logo textTech

연결 리스트

마지막 업데이트

연결 리스트는 시퀀스를 노드들의 사슬로 저장하며, 각 노드는 값과 다음 노드를 가리키는 포인터를 담습니다. 배열과 달리 노드들은 메모리에서 연속적이지 않으며, 리스트를 따라가려면 next 포인터를 따라갑니다. 위의 재생을 눌러 노드가 앞과 뒤에서 연결되고, 사슬을 따라가며 값이 탐색되고, 포인터를 다시 연결하여 노드가 제거되는 모습을 지켜보세요.

앞에서의 삽입이나 삭제는 헤드만 다시 가리키면 되므로 O(1)입니다. 중간의 위치나 끝에 도달하는 것은 먼저 그곳까지 걸어가야 하므로 O(n)입니다. 이 절충점(양 끝은 저렴하지만 임의 접근이 없음)이 연결 리스트를 배열과 구별짓는 특징입니다.

시간 복잡도

연산복잡도비고
앞에 삽입O(1)헤드를 다시 가리킴
뒤에 삽입O(n)먼저 끝까지 걸어감 (꼬리 포인터가 있으면 O(1))
탐색O(n)next 포인터를 따라감
헤드 삭제O(1)헤드를 그 너머로 다시 가리킴
인덱스로 접근O(n)임의 접근 없음

연결 리스트 대 배열

측면연결 리스트배열
메모리흩어진 노드 + 포인터연속된 블록
임의 접근O(n)O(1)
앞에서 삽입/삭제O(1)O(n) (이동)
캐시 친화성나쁨좋음

풀이 예제

리스트 [10, 20]를 만들고, 5를 앞에 붙인 다음, 20을 삭제하기:

단계구조동작
시작head -> null빈 리스트
앞에 10 삽입head -> 10 -> nullnext가 이전 헤드(null)인 새 노드로 헤드를 다시 가리킴
뒤에 20 삽입head -> 10 -> 20 -> null노드 10까지 걸어가 그 next를 새 노드 20으로 설정
앞에 5 삽입head -> 5 -> 10 -> 20 -> null새 노드 5가 이전 헤드 10을 가리키고, 헤드는 이제 5를 가리킴
20 삭제head -> 5 -> 10 -> null10까지 걸어가 그 next를 20에서 null로 설정; 노드 20은 연결이 끊김

연결 리스트를 사용할 때

사용할 때피해야 할 때
인덱싱보다 양 끝(또는 이미 쥐고 있는 노드)에서 삽입하거나 삭제하는 일이 훨씬 많을 때위치별 빠른 임의 접근(O(1) 인덱싱)이 필요할 때
크기가 많이 변하고 크기 조정/복사 비용을 원하지 않을 때캐시 지역성이 성능을 좌우하는 촘촘한 루프를 돌 때
큐, 스택 또는 인접 리스트를 구축할 때메모리가 빠듯할 때 - 각 노드는 요소마다 추가 포인터 비용을 치름
다른 곳에서의 삽입에도 살아남는 노드에 대한 안정적인 참조가 필요할 때주로 읽고 거의 수정하지 않아 배열이 더 단순하고 빠를 때

Linked List 코드

Python, JavaScript, Java, C++, C로 작성된 깔끔하고 실행 가능한 Linked List 구현입니다. 언어를 선택해 코드를 복사하거나 Coddy 플레이그라운드에서 바로 열어보세요.

Python로 구현한 Linked List 코드

Python
1class Node:2    def __init__(self, value):3        self.value = value4        self.next = None5
6
7class LinkedList:8    def __init__(self):9        self.head = None10
11    def append(self, value):12        node = Node(value)13        if self.head is None:14            self.head = node15            return16        current = self.head17        while current.next:18            current = current.next19        current.next = node20
21    def find(self, value):22        current = self.head23        while current:24            if current.value == value:25                return True26            current = current.next27        return False28
29    def delete(self, value):30        # Re-link the previous node around the match31        current, prev = self.head, None32        while current:33            if current.value == value:34                if prev is None:35                    self.head = current.next36                else:37                    prev.next = current.next38                return True39            prev, current = current, current.next40        return False41
42    def __str__(self):43        values, current = [], self.head44        while current:45            values.append(str(current.value))46            current = current.next47        return " -> ".join(values) + " -> None"48
49
50lst = LinkedList()51for value in [3, 7, 1, 9]:52    lst.append(value)53
54print("List:    ", lst)55print("find(7): ", lst.find(7))56lst.delete(1)57print("After delete(1):", lst)
이 코드를 Python 플레이그라운드에서 실행하기

연결 리스트 자주 묻는 질문

연결 리스트와 배열의 차이는 무엇인가요?
배열은 요소를 하나의 연속된 블록에 저장하여 O(1) 임의 접근을 제공하지만, 요소를 이동시키는 삽입/삭제는 O(n)입니다. 연결 리스트는 노드를 메모리 어디에나 포인터로 연결하여 저장하므로 알려진 위치에서의 삽입/삭제는 O(1)이지만, 사슬을 따라가야 하므로 접근은 O(n)입니다.
언제 연결 리스트를 사용해야 하나요?
연결 리스트는 양 끝(또는 이미 참조를 쥐고 있는 노드)에서 자주 삽입하거나 제거하고 임의 접근이 거의 필요 없을 때, 예를 들어 큐, 스택, 인접 리스트, LRU 캐시에서 빛을 발합니다. 빠른 인덱스 접근이 필요하다면 배열이나 동적 배열이 대개 더 낫습니다.
연결 리스트의 시간 복잡도는 어떻게 되나요?
헤드에서의 삽입이나 삭제는 O(1)입니다. 탐색, 또는 꼬리 포인터 없이 끝에 도달하는 것은 next 포인터를 하나씩 따라가므로 O(n)입니다. O(1) 임의 접근은 없습니다. 연결 리스트를 인덱싱하는 것은 O(n)입니다.
단일 연결 리스트와 이중 연결 리스트의 차이는 무엇인가요?
단일 연결 리스트는 노드마다 next 포인터만 저장하므로 한 방향으로만 갈 수 있고, 노드를 삭제하려면 그 앞 노드에 대한 참조가 필요합니다. 이중 연결 리스트는 prev 포인터를 추가하여 뒤로의 순회와 쥐고 있는 노드의 O(1) 삭제를 가능하게 하지만, 노드마다 추가 포인터와 모든 삽입·삭제 시 더 많은 관리 비용이 듭니다.
앞에 삽입하는 것이 O(1)인데 왜 뒤에 삽입하는 것은 O(n)인가요?
앞에 삽입하는 것은 head 포인터만 다시 연결하므로 상수 작업입니다. 끝에 도달하려면 헤드에서 끝까지 next 포인터를 따라가야 하므로 O(n)입니다. 별도의 tail 포인터를 유지하면 뒤에 삽입하는 것도 O(1)이 되므로, 실제 리스트는 종종 양 끝을 모두 추적합니다.
연결 리스트는 어디서나 O(1) 삽입이 가능한가요?
아니요, 그것은 흔한 오해입니다. 삽입 자체는 삽입할 위치의 앞 노드에 대한 포인터를 이미 쥐고 있을 때만 O(1)입니다. 그 위치를 값이나 인덱스로 찾는 것은 그곳에 도달하기 위해 사슬을 따라가야 하므로 여전히 O(n)이 듭니다.
Coddy programming languages illustration

Coddy로 알고리즘을 마스터하세요

시작하기