문서 목적 해당 문서는 대학원 과정 중 파이썬과 자료구조에 대해 정리하고자 작성된 문서이다.
선형 자료구조로, Python에서는 이를 기본적으로 제공한다.
i번 자리에 원소 x를 삽입한다.
i번 원소를 삭제한다.
원소 x를 삭제한다.
i번 원소를 알려준다.
원소 x가 몇 번 원소인지 알려준다.
리스트의 사이즈(원소의 총 수)를 알려준다.
insert(x, i)
: x를 리스트의 i번 원소로 삽입append(x)
: 원소 x를 리스트의 맨 뒤에 추가data.insert(len(data), x)
와 같음pop(i)
: i번째 원소를 삭제하면서 알려준다.remove(x)
: 리스트에서 처음으로 나타나는 x를 삭제한다. index(x)
: x가 리스트의 몇 번 원소인지 알려준다.clear()
: 리스트를 깨끗이 청소한다.count(x)
: x가 몇번 나타나는지 알려준다.extend(a)
: 리스트에 나열할 수 있는 객체 a를 풀어서 추가copy()
: 리스트를 복사reverse()
: 리스트의 순서를 역으로 뒤집는다.sort()
: 리스트 정렬count = 1000
result = [0 for _ in range]
for i in range(count):
result[i] += 1
__head
: 첫 번째 노드에 대한 레퍼런스__numItems
: 연결 리스트에 들어 있는 원소의 총 수insert(i, x)
: x를 연결 리스트의 i번 원소로 삽입한다.append(x)
: 연결 리스트의 맨 뒤에 원소 x를 추가한다.pop(i)
: 연결 리스트의 i번 원소를 삭제하면서 알려준다.remove(x)
: 연결 리스트에서 처음으로 나타나는 x를 삭제한다.get(i)
: 연결 리스트의 i번 원소를 알려준다.index(x)
: 원소 x가 연결리스트의 몇 번 원소인지 알려준다.isEmpty()
: 연결 리스트가 비어 있는지 알려준다.size()
: 연결 리스트의 총 원소 수를 알려준다.clear()
: 연결 리스트를 깨끗이 청소한다.count(x)
: 연결 리스트에서 원소 x가 몇 번 나타나는지 알려준다.extend(a)
: 연결 리스트에서 나열할 수 있는 객체 a를 풀어서 추가한다.copy()
: 연결 리스트를 복사해서 새 연결 리스트를 리턴한다.reverse()
: 연결 리스트의 순서를 역으로 뒤집는다.sort()
: 연결 리스트를 정렬한다.sort는 나중에...ㅎㅎ
class Node:
def __init__(self, data, nextNode=None):
self.data = data
self.nextNode = nextNode
class LinkedList:
# TODO: sort, reverse 추가
def __init__(self, node=None):
self.__head = node
self.__numItems = 0 if node is None else 1
def __check_valid_node(self, node):
if node.__class__.__name__ != 'Node':
raise ValueError(f'x must be Node class, but got {node.__class__.__name__}')
def __get_node_item(self, i):
if self.__numItems <= i:
raise IndexError(f'max_size is {self.__numItems} but got {i}')
curNode = self.__head
for _ in range(i):
curNode = curNode.nextNode
return curNode
def __get_last_node_item(self):
curNode = self.__head
while curNode.nextNode is not None:
curNode = curNode.nextNode
return curNode
def insert(self, i, x):
# `insert(i, x)` : x를 연결 리스트의 i번 원소로 삽입한다.
self.__check_valid_node(x)
curNode = self.__get_node_item(i)
nextNode = curNode.nextNode
curNode.nextNode = x
x.nextNode = nextNode
self.__numItems += 1
self.describe()
def append(self, x):
#`append(x)` : 연결 리스트의 맨 뒤에 원소 x를 추가한다.
self.__check_valid_node(x)
if self.__numItems == 0:
self.__head = x
else:
curNode = self.__get_last_node_item()
curNode.nextNode = x
self.__numItems += 1
self.describe()
def pop(self, i):
# `pop(i)` : 연결 리스트의 i번 원소를 삭제하면서 알려준다.
curNode = self.__get_node_item(i-1)
removedNode = curNode.nextNode
removedNextNode = removedNode.nextNode if removedNode is not None else None
curNode.nextNode = removedNextNode
self.__numItems -= 1
self.describe()
return removedNode
def remove(self, x):
# `remove(x)` : 연결 리스트에서 처음으로 나타나는 x를 삭제한다.
pervNode = None
isChanged = False
curNode = self.__head
while curNode is not None:
if curNode.data == x.data:
if pervNode is None:
self.__head = curNode.nextNode
else:
pervNode.next = curNode.nextNode
isChanged = True
break
curNode = curNode.nextNode
pervNode = curNode
if isChanged:
self.__numItems -= 1
else:
raise ValueError(f'{x} is not in Linkedlist')
self.describe()
def get(self, i):
# `get(i)` : 연결 리스트의 i번 원소를 알려준다.
return self.__get_node_item(i)
def index(self, x):
# `index(x)` : 원소 x가 연결리스트의 몇 번 원소인지 알려준다.
idx = 0
curNode = self.__head
isFind = False
while curNode is not None:
if curNode.data == x.data:
isFind=True
return idx
idx += 1
curNode = curNode.nextNode
if not isFind:
raise ValueError(f'{x} is not in Linkedlist')
def isEmpty(self):
# `isEmpty()` : 연결 리스트가 몇 번 원소인지 알려준다.
return True if self.__numItems == 0 else False
def size(self):
# `size()` : 연결 리스트의 총 원소 수를 알려준다.
return self.__numItems
def clear(self):
# `clear()` : 연결 리스트를 깨끗이 청소한다.
self.__head = None
self.__numItems = 0
def count(self, x):
# `count(x)` : 연결 리스트에서 원소 x가 몇 번 나타나는지 알려준다.
count = 0
curNode = self.__head
while curNode is not None:
if curNode.data == x.data:
count += 1
curNode = curNode.nextNode
return count
def extend(a):
# `extend(a)` : 연결 리스트에서 나열할 수 있는 객체 a를 풀어서 추가한다.
lastNode = self.__get_last_node_item()
if a.__class__.__name__ == 'LinkedList':
lastNode.next(a.__head)
else:
for node_i in a:
self.append(node_i)
self.describe()
def copy():
# `copy()` : 연결 리스트를 복사해서 새 연결 리스트를 리턴한다.
newLinkedList = LinkedList()
curNode = self.__head
while curNode.nextNode is not None:
newLinkedList.append(curNode)
curNode = curNode.nextNode
return newLinkedList
def describe(self):
curNode = self.__head
list_i = []
for _ in range(self.__numItems):
list_i.append(curNode.data)
curNode = curNode.nextNode if curNode is not None else None
print(list_i)
끝 노드(tail)의 nextNode가 None을 갖는 대신 첫 노드를 링크한다
맨 앞과 맨 뒤의 접근성 차이가 없어짐
각 노드가 nextNode만 가지고 있는 것이 아닌 prevNode 또한 링크함
head의 경우 prevNode는 Node을 갖고 있음
원형 연결 리스트 + 양방향 연결 리스트