접근(Access)
삽입(Insertion)
삭제(Deletion)
__init__
메서드는 노드를 초기화하고 데이터를 저장하며, 다음 노드에 대한 참조 (next)를 초기화합니다.__init__
메서드는 연결 리스트의 헤드 (head)와 테일 (tail) 노드, 그리고 리스트의 크기를 초기화합니다.class Node:
def __init__(self, data):
self.data = data
self.next = None
class SinglyLinkedList:
def __init__(self):
self.head = None
self.tail = None
self.size = 0
def addFirst(self, e):
new_node = Node(e)
if self.head is None:
self.head = new_node
self.tail = new_node
else:
new_node.next = self.head
self.head = new_node
self.size += 1
def addLast(self, e):
new_node = Node(e)
if self.tail is None:
self.head = new_node
self.tail = new_node
else:
self.tail.next = new_node
self.tail = new_node
self.size += 1
def add(self, index, e):
if not (0 <= index <= self.size):
raise IndexError("Index: {}, Size: {}".format(index, self.size))
if index == self.size:
self.addLast(e)
elif index == 0:
self.addFirst(e)
else:
prev_node = self.get_node(index - 1)
new_node = Node(e)
new_node.next = prev_node.next
prev_node.next = new_node
self.size += 1
def get_node(self, index):
if not (0 <= index < self.size):
raise IndexError("Index: {}, Size: {}".format(index, self.size))
current_node = self.head
for _ in range(index):
current_node = current_node.next
return current_node
def get(self, index):
return self.get_node(index).data
def set(self, index, e):
if not (0 <= index < self.size):
raise IndexError("Index: {}, Size: {}".format(index, self.size))
current_node = self.get_node(index)
old_data = current_node.data
current_node.data = e
return old_data
def remove(self, index):
if not (0 <= index < self.size):
raise IndexError("Index: {}, Size: {}".format(index, self.size))
if index == 0:
removed_node = self.head
self.head = self.head.next
if self.size == 1:
self.tail = None
elif index == self.size - 1:
prev_node = self.get_node(index - 1)
removed_node = prev_node.next
prev_node.next = None
self.tail = prev_node
else:
prev_node = self.get_node(index - 1)
removed_node = prev_node.next
prev_node.next = removed_node.next
self.size -= 1
return removed_node.data
def print_list(self):
current_node = self.head
while current_node is not None:
print(current_node.data, end=" -> ")
current_node = current_node.next
print("None")
테스트 결과
if __name__ == "__main__":
linked_list = SinglyLinkedList()
linked_list.addFirst("A-")
linked_list.addFirst("A")
linked_list.addLast("A+")
linked_list.print_list() # (0) A, (1) A-, (2) A+
node = linked_list.get_node(2)
print("node =", node.data)
linked_list.add(0, "N")
linked_list.add(2, "P")
linked_list.add(5, "Q")
print(" ======================== ")
linked_list.print_list()
print(" ======================== ")
linked_list.set(5, "New Q")
linked_list.set(0, "New N")
linked_list.print_list()
print(" ======================== ")
remove1 = linked_list.remove(5)
remove2 = linked_list.remove(3)
remove3 = linked_list.remove(0)
linked_list.print_list()
A -> A- -> A+ -> None
node = A+
========================
N -> A -> P -> A- -> A+ -> Q -> None
========================
New N -> A -> P -> A- -> A+ -> New Q -> None
========================
A -> P -> A+ -> None
__init__
메서드는 노드를 초기화하고 데이터를 저장하며, 이전과 다음 노드에 대한 참조 (prev, next)를 초기화합니다.class BidirectionalNode:
def __init__(self, data):
self.prev = None
self.data = data
self.next = None
class DoublyLinkedList:
def __init__(self):
self.dummy_head = BidirectionalNode(None)
self.dummy_tail = BidirectionalNode(None)
self.dummy_head.next = self.dummy_tail
self.dummy_tail.prev = self.dummy_head
self.size = 0
def add_first(self, e):
new_node = BidirectionalNode(e)
new_node.next = self.dummy_head.next
new_node.prev = self.dummy_head
self.dummy_head.next.prev = new_node
self.dummy_head.next = new_node
self.size += 1
def add_last(self, e):
new_node = BidirectionalNode(e)
new_node.next = self.dummy_tail
new_node.prev = self.dummy_tail.prev
self.dummy_tail.prev.next = new_node
self.dummy_tail.prev = new_node
self.size += 1
def add(self, index, e):
if not (0 <= index <= self.size):
raise IndexError(f"Index: {index}, Size: {self.size}")
prev_node = self.get_node(index - 1)
new_node = BidirectionalNode(e)
new_node.prev = prev_node
new_node.next = prev_node.next
prev_node.next.prev = new_node
prev_node.next = new_node
self.size += 1
def get_node(self, index):
if not (-1 <= index < self.size):
raise IndexError(f"Index: {index}, Size: {self.size}")
current_node = None
if index < self.size // 2:
current_node = self.dummy_head
for i in range(-1, index + 1):
current_node = current_node.next
else:
current_node = self.dummy_tail
for i in range(self.size, index, -1):
current_node = current_node.prev
return current_node
def get(self, index):
return self.get_node(index).data
def set(self, index, e):
if not (0 <= index < self.size):
raise IndexError(f"Index: {index}, Size: {self.size}")
current_node = self.get_node(index)
old_data = current_node.data
current_node.data = e
return old_data
def remove(self, index):
if not (0 <= index < self.size):
raise IndexError(f"Index: {index}, Size: {self.size}")
current_node = self.get_node(index)
current_node.prev.next = current_node.next
current_node.next.prev = current_node.prev
self.size -= 1
def print_list(self):
current_node = self.dummy_head
print("dummy head <->", end=" ")
while current_node.next != self.dummy_tail:
current_node = current_node.next
print(current_node.data, end=" <-> ")
print("dummy tail")
테스트 코드
if __name__ == "__main__":
linked_list = DoublyLinkedList()
# add_first() 테스트
linked_list.add_first(3)
linked_list.add_first(2)
linked_list.add_first(1)
print("add_first() 후: ")
linked_list.print_list()
# add_last() 테스트
linked_list.add_last(4)
linked_list.add_last(5)
print("add_last() 후: ")
linked_list.print_list()
# add(index, element) 테스트
linked_list.add(0, 0) # 처음에 0 추가
linked_list.add(6, 6) # 마지막에 6 추가
linked_list.add(4, 99) # 4번 인덱스에 99 추가
print("add(index, element) 후: ")
linked_list.print_list()
# get(index) 테스트
print("인덱스 3의 요소: " + str(linked_list.get(3))) # 예상 결과: 인덱스 3의 요소: 99
# set(index, element) 테스트
linked_list.set(4, 100) # 인덱스 4의 요소를 100으로 변경
print("set(index, element) 후: ")
linked_list.print_list()
# remove(index) 테스트
linked_list.remove(0) # 첫 번째 요소 제거
linked_list.remove(6) # 마지막 요소 제거
print("remove(index) 후: ")
linked_list.print_list()
add_first() 후:
dummy head <-> 1 <-> 2 <-> 3 <-> dummy tail
add_last() 후:
dummy head <-> 1 <-> 2 <-> 3 <-> 4 <-> 5 <-> dummy tail
add(index, element) 후:
dummy head <-> 1 <-> 0 <-> 2 <-> 3 <-> 99 <-> 4 <-> 5 <-> 6 <-> dummy tail
인덱스 3의 요소: 99
set(index, element) 후:
dummy head <-> 1 <-> 0 <-> 2 <-> 3 <-> 100 <-> 4 <-> 5 <-> 6 <-> dummy tail
remove(index) 후:
dummy head <-> 1 <-> 2 <-> 3 <-> 100 <-> 4 <-> 5 <-> dummy tail
__init__
메서드는 노드를 초기화하고 데이터를 저장하며, 다음 노드에 대한 참조 (next)를 초기화합니다.class BidirectionalNode:
def __init__(self, data=None, prev=None, next=None):
self.prev = prev
self.data = data
self.next = next
class CircularDoublyLinkedList:
def __init__(self):
self.dummyHead = BidirectionalNode()
self.dummyTail = BidirectionalNode()
self.dummyHead.next = self.dummyTail
self.dummyTail.prev = self.dummyHead
self.dummyHead.prev = self.dummyTail
self.dummyTail.next = self.dummyHead
self.size = 0
def addFirst(self, e):
new_node = BidirectionalNode(e)
new_node.next = self.dummyHead.next
new_node.prev = self.dummyHead
self.dummyHead.next.prev = new_node
self.dummyHead.next = new_node
self.size += 1
def addLast(self, e):
new_node = BidirectionalNode(e)
new_node.next = self.dummyTail
new_node.prev = self.dummyTail.prev
self.dummyTail.prev.next = new_node
self.dummyTail.prev = new_node
self.size += 1
def add(self, index, e):
if not (0 <= index <= self.size):
raise IndexError(f"Index: {index}, Size: {self.size}")
prev_node = self.getNode(index - 1)
new_node = BidirectionalNode(e)
new_node.prev = prev_node
new_node.next = prev_node.next
prev_node.next.prev = new_node
prev_node.next = new_node
self.size += 1
def getNode(self, index):
if not (-1 <= index < self.size):
raise IndexError(f"Index: {index}, Size: {self.size}")
if index < self.size // 2:
current_node = self.dummyHead
for _ in range(index + 1):
current_node = current_node.next
return current_node
else:
current_node = self.dummyTail
for _ in range(self.size - index):
current_node = current_node.prev
return current_node
def get(self, index):
if not (0 <= index < self.size):
raise IndexError(f"Index: {index}, Size: {self.size}")
return self.getNode(index).data
def set(self, index, e):
if not (0 <= index < self.size):
raise IndexError(f"Index: {index}, Size: {self.size}")
current_node = self.getNode(index)
old_data = current_node.data
current_node.data = e
return old_data
def remove(self, index):
if not (0 <= index < self.size):
raise IndexError(f"Index: {index}, Size: {self.size}")
current_node = self.getNode(index)
current_node.prev.next = current_node.next
current_node.next.prev = current_node.prev
self.size -= 1
return current_node.data
def print(self):
curr_node = self.dummyHead
print("dummy head <-> ", end="")
while curr_node.next != self.dummyTail:
curr_node = curr_node.next
print(f"{curr_node.data} <-> ", end="")
print("dummy tail <-> dummy head")