Hi, There!
안녕하세요, 바오밥입니다.
목차
- 개요
- 본문
- Reference
개요
지금까지 스택, 큐, 배열 등 정말 기초적인 자료 구조를 알아보았습니다.
이어서 링크드 리스트에 대해 알아보도록 하겠습니다.
본문
링크드 리스트 (Linked List) 구조
- 배열은 순차적인 메모리 공간에 데이터를 나열하는 구조인 반면, 링크드 리스트는 떨어진 곳에 존재하는 데이터를 참조하여 관리하는 데이터 구조입니다.
- C 언어에서 주요한 데이터 구조이지만, 파이썬은 리스트 타입이 링크드 리스트의 기능을 모두 지원합니다.
그래서 C언어와 다르게 파이썬은 별도의 리스트의 크기를 지정하지 않고 선언할 수 있습니다.
링크드 리스트 기본 구조와 용어
- 노드(Node) : 데이터 저장 단위를 뜻하며 값, 포인터(참조 정보)로 구성되어 있습니다.
- 포인터(Pointer) : 각 노드 안에서 다음이나 이전의 노드와의 연결(참조) 정보를 가지고 있는 공간입니다.
- 링크드 리스트의 마지막 노드를 제외한 모든 노드는 포인터에 메모리의 주소 값으로 매핑되어 있습니다.
링크드 리스트의 마지막 노드는 메모리의 주소 값 대신 널 값이 매핑되어 있고, 이는 리스트의 끝을 의미합니다.
단방향 링크드 리스트 예제
Node 구현
class Node:
def __init__(self, data):
self.data = data
self.next = None
Linked List 구현
class LinkedList:
def __init__(self, data):
self.head = Node(data)
self.next = None
def append(self, data):
cur = self.head
while cur.next:
cur = cur.next
cur.next = Node(data)
def showNodeAll(self):
cur = self.head
while cur:
print(cur.data)
cur = cur.next
def insert(self, prev, data):
cur = self.head
isDataPos = True
while isDataPos:
if cur.data == prev:
prevNode = cur
nextNode = cur.next
prevNode.next = Node(data)
newNode = prevNode.next
newNode.next = nextNode
isDataPos = False
else:
cur = cur.next
def delete(self, data):
cur = self.head
if cur == '':
print('삭제할 요소가 존재하지 않습니다.')
return
if cur.data == data:
temp = self.head
self.head = self.head.next
del temp
else:
isDataPos = True
while isDataPos:
if cur.next.data == data:
temp = cur.next
cur.next = cur.next.next
del temp
isDataPos = False
else:
cur = cur.next
def searchNode(self, data):
idx = 1
cur = self.head
while cur:
if cur.data == data:
print("검색하신 데이터는",str(idx)+"번째 노드입니다.")
return
else:
idx += 1
cur = cur.next
링크드 리스트, 노드 사이의 새로운 노드를 만들 때 일어나는 상황을 표현한 그림
링크드 리스트의 장단점 (배열 VS 링크드 리스트)
장점
- 미리 데이터 공간을 할당하지 않아도 됩니다.
*배열은 미리 데이터 공간을 할당해야 합니다.
단점
- 연결(참조 주소)을 위한 별도 데이터 공간이 필요하므로, 저장공간 효율이 높지 않습니다.
- 연결 정보(참조 주소)를 찾는 시간이 필요하므로 접근 속도가 비교적 느립니다.
*배열은 인덱스 번호로 바로 접근이 가능합니다. - 중간 데이터 삭제 시, 앞뒤 데이터의 연결을 재구성해야 하는 부가적인 작업이 필요합니다.
더블 링크드 리스트(이중 연결 리스트)의 구조
- 이중 연결리스트는 양방향으로 연결되어 있어서 노드 탐색이 양쪽으로 가능합니다.
더블 링크드 리스트(이중 연결 리스트)의 예제
Node 구현
class Node:
def __init__(self,data):
self.prev = None
self.data = data
self.next = None
Double Linked List 구현
class Node:
def __init__(self,data):
self.prev = None
self.data = data
self.next = None
class DoubleLinkedList:
def __init__(self,data):
self.head = Node(data)
self.tail = self.head
def append(self, data):
cur = self.head
while cur.next:
cur = cur.next
newNode = Node(data)
cur.next = newNode
newNode.prev = cur
self.tail = newNode
def insertPrev(self, prevData, data):
cur = self.head
while cur:
if cur.data == prevData:
prevNode = cur
newNode = Node(data)
nextNode = cur.next
newNode.prev = prevNode
newNode.next = nextNode
nextNode.prev = newNode
prevNode.next = newNode
break
else:
cur = cur.next
def insertNext(self, nextData, data):
cur = self.head
while cur:
if cur.data == nextData:
prevNode = cur
newNode = Node(data)
nextNode = cur.next
newNode.prev = prevNode
newNode.next = nextNode
nextNode.prev = newNode
prevNode.next = newNode
break
else:
cur = cur.next
def searchFromHead(self,data):
cur = self.head
idx = 1
while cur:
if cur.data == data:
print(f'데이터: {data}는 앞에서 {idx}번째 노드입니다.')
break
else:
cur = cur.next
idx += 1
def searchFromTail(self,data):
cur = self.tail
idx = 1
while cur:
if cur.data == data:
print(f'데이터: {data}는 뒤에서 {idx}번째 노드입니다.')
break
else:
cur = cur.prev
idx += 1
def showNodeAll(self):
cur = self.head
while cur:
print(cur.data)
cur = cur.next
Reference
- 코드 없는 알고리즘과 데이터 구조
- 알고리즘 / 기술면접 완전 정복 올인원 패키지 Online.
'Theory > Algorithm & Data Structure' 카테고리의 다른 글
[자료구조] 근본 자료구조인 연결리스트에 대해서 (0) | 2023.12.03 |
---|---|
[자료구조] 누구나 아는 배열에 대해서 (0) | 2023.12.03 |
[자료구조] 스택(Stack) (0) | 2021.08.03 |
[자료구조] 큐(Queue) (0) | 2021.07.28 |
[자료구조] 배열(Array) (0) | 2021.07.26 |