언어/Python
[Python] 양방향 연결리스트 구현
더날고싶은sm
2024. 4. 12. 22:30
class Node:
def __init__(self, data):
self.data = data
self.prev = None
self.next = None
class DoublyLinkedList:
def __init__(self):
self.head = None
self.tail = None
def add(self, data):
new_node = Node(data)
if self.head is None: # 비어있는 노드일 때
self.head = new_node
self.tail = new_node
#new_node.prev = self.head
#new_node.next = self.tail
else: # 비어있는 노드가 아닐 때
new_node.prev = self.tail # 1. 새로운 노드의 prev에 이미 저장되어 있는 노드의 tail을 가르킴
self.tail.next = new_node
self.tail = new_node
def remove(self, data):
current = self.head
while current is not None:
if current.data == data:
if current.prev is not None: # 노드가 2번째 이상인 data를 없앨 때
current.prev.next = current.next # self.head.prev의 node의 next를 current.next인 노드와 연결
else: # 단일 노드일 때
self.head = None
if current.next is not None: # 양방향 연결리스트이므로 next도 다음 노드의 이전과 연결
current.next.prev = current.prev
else: # 단일 노드일 때
self.tail = None
break
current = current.next
def search(self, data):
current = self.head
while current is not None:
if current.data == data:
return True
current = current.next # data를 찾을 때까지 다음 노드로 계속 이동
return False
def print_forward(self):
current = self.head
if self.head is None:
print("데이터가 없습니다.")
return
while current is not None:
print(current.data, end=" ")
current = current.next
print()
def print_backward(self):
current = self.tail
while current is not None:
print(current.data, end=" ")
current = current.prev
print()
def insert(self, data, index):
if index < 0 or index > self.length(): # 예외처리
raise IndexError("Invalid index")
new_node = Node(data)
if index == 0: # index 0 번째에 삽입
if self.head is None: # 연결리스트에 아무것도 없을 때
self.head = new_node
self.tail = new_node
else: # 연결리스트에 값이 있지만 0번 째 index에 삽입
new_node.next = self.head # 지금 self.head는 기존 노드의 index 0을 가르키고 있으므로 new_node의 next에 값을 대입
self.head.prev = new_node # self.head.prev를 하면 기존 노드의 index 0의 prev노드에 new_node를 가르키게 한다.
self.head = new_node # 새로운 노드와 index 0인 노드가 서로 연결되었으니 self.head는 new_node를 가르키게 한다.
elif index == self.length(): # 마지막에 삽입
self.add(data)
else:
current = self.head
# for문으로 current가 다음 노드를 가르키고 끝나는 것이 아니라 index-1이므로 1 번째에 값을 삽입하면
# 0 번째 노드를 가르키고 for문을 탈출함 즉, index가 0에서 새로운 노드를 삽입하는 것임
for _ in range(index - 1): # 예시) insert(4,1)
current = current.next # 0번째 index의 next, 기존의 data 2 노드를 가르킨다.
new_node.next = current.next # new_node.next를 data가 2인 노드를 가르키게 한다.
new_node.prev = current # current는 현재 index 0이다. new_node의 prev에 index 0번째를 가르킨다.
current.next.prev = new_node # data 2인 노드의 prev에 new_node를 가르키도록 한다.
current.next = new_node # 현재 data 2인 노드를 가르키고 있으므로 new_node를 가르키도록 한다.
def length(self):
count = 0
current = self.head
while current is not None:
count += 1
current = current.next # 노드 개수를 계산하기 위해 다음 노드를 가르킨다.
return count
#예시 실행
doubly_linked_list = DoublyLinkedList()
# 노드 추가
doubly_linked_list.add(1)
doubly_linked_list.add(2)
doubly_linked_list.add(3)
# 전체 리스트 출력 (순방향)
print("Forward: ", end="")
doubly_linked_list.print_forward() # Output: 1 2 3
# 전체 리스트 출력 (역방향)
print("Backward: ", end="")
doubly_linked_list.print_backward() # Output: 3 2 1
# 노드 삽입
doubly_linked_list.insert(4, 1) # 1 4 2 3
doubly_linked_list.insert(5, 0) # 5 1 4 2 3
doubly_linked_list.insert(6, 5) # 5 1 4 2 3 6
# # 전체 리스트 출력 (순방향)
print("Forward: ", end="")
doubly_linked_list.print_forward() # Output: 5 1 4 2 3 6
# 전체 리스트 출력 (역방향)
print("Backward: ", end="")
doubly_linked_list.print_backward() # Output: 6 3 2 4 1 5
# 노드 제거
doubly_linked_list.remove(4)
# 전체 리스트 출력 (순방향)
print("Forward: ", end="")
doubly_linked_list.print_forward() # Output: 5 1 2 3 6