

'꼬리에 꼬리를 무는 그날 이야기'라는 프로그램이 있죠. 우리는 '꼬리에 꼬리를 무는 연결 리스트'에 대해 알아보도록 합시다.

data 속성: 노드가 저장하는 데이터 값next 속성: 다음 노드를 가리키며, 다른 Node 인스턴스를 참조class Node:
def __init__(self, data=None, next=None):
self.data = data # 저장값
self.next = next # 다음 노드
class LinkedList:
def __init__(self):
# 노드가 없는 빈 연결 리스트 생성
self.head = None # 머리 노드
# 이후 메서드는 뒤에서 구현
속성 정의
head 속성: 머리 노드를 참조head가 None인 경우: 노드가 하나도 없는, 빈 연결 리스트
head가 새로 삽입한 노드를 가리키도록 수정한다.# 머리에 노드 삽입
def add_first(self, x):
# (1) 삽입할 노드를 생성한다.
insert_node = Node(data=x, next=self.head)
# (2) `head`가 새로 삽입한 노드를 가리키도록 수정한다.
self.head = insert_node

prev를 찾는다.prev의 다음 노드를 설정한다.prev의 다음 노드를, 새로 생성한 노드로 변경한다.# where번째 위치에 노드 삽입
def add(self, x, where):
# 맨 앞에 삽입하는 경우
if where == 0:
self.add_first(x)
return
# (1) 삽입 위치 이전에 위치한 노드 `prev` 찾기
prev = self.head
i = 0
while prev is not None and i < where - 1:
prev = prev.next
i += 1
if prev is None:
print("삽입 위치가 인덱스 길이보다 큽니다")
return
# (2) 삽입할 노드를 생성
insert_node = Node(data=x, next=prev.next)
# (3) prev의 다음 노드를 새로 생성한 노드로 변경
prev.next = insert_node

# where번째 위치의 노드 데이터 확인
def index(self, where):
curr = self.head
i = 0
# 찾고자 하는 위치의 노드까지 이동
while curr is not None and i < where:
curr = curr.next
i += 1
if curr is None:
print("탐색 위치가 인덱스 길이보다 큽니다")
return
return curr.data

head가 기존 머리 노드의 다음 노드 head.next를 가리키도록 업데이트한다.# 머리 노드 삭제
def remove_first(self):
# 연결 리스트가 비어 있지 않아야 함
if self.head is not None:
# 기존 머리 노드의 다음 노드로 업데이트
self.head = self.head.next

prev를 찾는다.prev의 다음 노드를, 삭제할 노드의 다음 노드로 업데이트한다.# where번째 위치의 노드 삭제
def remove(self, where):
# 연결 리스트가 비어 있지 않아야 함
if self.head is not None:
# 첫 노드를 삭제하는 경우
if where == 0:
self.remove_first()
return
# (1) 삭제할 노드 앞에 위치한 노드 `prev`를 찾는다.
prev = self.head
i = 0
while prev is not None and i < where - 1:
prev = prev.next
i += 1
if prev is None or prev.next is None:
print("삭제 위치가 인덱스 길이보다 큽니다")
return
# (2) `prev`의 다음 노드를, 삭제할 노드의 다음 노드로 업데이트
prev.next = prev.next.next
맨 앞에 값 삽입
head가 가리키는 노드만 바꿔 주면 됨중간에 값 삽입 / 삭제
맨 끝에 값 삽입 / 삭제
i번째 원소 접근
A[i]로 바로 가능0번째 ~ i-1번째 노드를 거쳐야 함

deque🤔 그래서 이중 연결 리스트가 뭔지는 알겠는데, 실제로 파이썬에서 이걸 활용하는 자료구조가 있나요?
collections.deque 자료구조는 이중 원형 연결 리스트와 유사하게 구현되어 있습니다.list의 경우, 맨 앞에 원소를 추가 (list.insert(0, x))하거나 제거 (list.pop(0))할 때 이 소요됐었죠.deque는 연결 리스트로 구현되어 있으니, 맨 앞 원소를 list보다 빠른 에 제거/삽입할 수 있습니다.deque.appendleft(): 맨 앞에 원소를 삽입, deque.popleft(): 맨 앞 원소를 꺼내 반환, list와 동일하게 에 제거/삽입할 수 있습니다.deque.append(), deque.pop()은 여전히 사용 가능하고, 소요deque에서도 인덱스를 이용해 특정 위치의 원소에 접근할 수 있습니다.list로 변환한 후 하는 게 좋습니다.from collections import deque
a = deque([1, 2, 3])
a.appendleft(0)
print(a) # deque([0, 1, 2, 3]), O(1)
a.popleft()
print(a) # deque([1, 2, 3]), O(1)
print(a[1]) # 2, O(N)
| 연산 | 배열 OR list | 연결 리스트 | 이중 원형 연결 리스트 OR deque |
|---|---|---|---|
| 맨 앞 원소 삽입/삭제 | |||
| 중간에 원소 삽입 | |||
| 맨 뒤 원소 삽입/삭제 | |||
| 원하는 위치의 원소 탐색 |
설명이 기깔나시네요 깃헙 팔로우합니다