デュアルチェーンテーブルの実装
class Node:
def __init__(self, value, next, prev):
self.value = value
self.next = next
self.prev = prev # 일반 연결리스트에 예전 노드로 돌아갈 수 있는 변수 추가
class DoublyLinkedList:
def __init__(self):
self.head = None
self.tail = None # 끝을 판단할 수 있는 변수 추가
self.length = 0
def is_empty(self):
if self.head == None:
return True
else:
return False
def prepend(self, value):
if self.head == None: # 노드가 아무것도 없는 경우
node = Node(value, None, None)
self.head = node
self.tail = node # 꼬리까지 노드로 지정
else: # 리스트가 존재할 경우
node = Node(value, self.head, None)
self.head.prev = node # 새로운 노드를 현재 헤드의 노드가 가르키게 함
self.head = node # 현재 헤드를 새로운 노드로 바꿔줌
self.length += 1
def append(self, value):
if self.tail == None:
node = Node(value, None, None)
self.head = node
self.tail = node
else:
node = Node(value, None, self.tail)
self.tail.next = node # 새로운 노드를 현재 꼬리가 가리키게 함
self.tail = node # 새로운 노드가 꼬리가 됨
# 기존 단방향 리스트는 끝까지 탐색해야 했는데, 양방향은 O(1)로 탐색 가능
self.length += 1
def set_head(self, index):
if self.length <= index or index < 0:
return "list index out of range"
else:
curr = self.head
for _ in range(index):
curr = curr.next
self.head = curr
self.head.prev = None
self.length -= index
def set_tail(self, index): # 헤드를 꼬리에서 부터 시작해주는 것 외에 다른 것 없음
if self.length <= index or index < 0:
return "list index out of range"
else:
curr = self.tail
for _ in range(self.length - index):
curr = curr.prev
self.tail = curr
self.tail.next = None
self.length -= (self.length - index)
def access(self, index):
if self.length <= index or index < 0:
return "list index out of range"
else:
if index >= self.length // 2:
# 인덱스가 절반보다 클 경우 tail에서부터 접근
# 양방향 리스트의 이점을 살리기 위해
curr = self.tail
for _ in range(self.length - index - 1):
curr = curr.prev
return curr.value
else:
# 반대일 경우 head에서부터 접근
curr = self.head
for _ in range(index):
curr = curr.next
return curr.value
def insert(self, index, value):
if self.length <= index or index < 0:
return "list index out of range"
else:
if index == 0:
self.prepend(value)
elif index == self.length-1:
self.append(value)
else:
if index >= self.length // 2:
# 인덱스가 절반보다 클 경우 tail에서부터 접근
curr = self.tail
for _ in range(self.length - index):
curr = curr.prev
node = Node(value, curr.next, curr)
curr.next = node
else:
# 반대일 경우 head에서부터 접근
curr = self.head
for _ in range(index-1):
curr = curr.next
node = Node(value, curr.next, curr)
curr.next = node
self.length += 1
def remove(self, index):
if self.length <= index or index < 0:
return "list index out of range"
else:
if index >= self.length // 2:
# 인덱스가 절반보다 클 경우 tail에서부터 접근
if index == self.length -1:
self.tail = self.tail.prev
self.tail.next = None
else:
curr = self.tail
for _ in range(self.length - index):
curr = curr.prev
curr.next = curr.next.next
curr.next.prev = curr
else:
# 반대일 경우 head에서부터 접근
if index == 0:
self.head = self.head.next
self.head.prev = None
else:
curr = self.head
for _ in range(index - 1):
curr = curr.next
curr.next = curr.next.next
curr.next.prev = curr
self.length -= 1
def print(self):
curr = self.head
while curr != None:
print(curr.value, end=" ")
curr = curr.next
print()
def print_inverse(self):
curr = self.tail
while curr != None:
print(curr.value, end=" ")
curr = curr.prev
print()
基本的には,双方向リストを実現する際には,一方向リストの欠点を補うことができるように実現すべきであると考えられる.特にappendは,最初から最後までn回移動しなければならないため,効率の悪いナビゲーションがあり,双方向リストでこれを解決できる.また,挿入,削除の際には,インデックスの位置に応じて2/n回移動するだけで見つけることができるため,いくつかの有効な検索が可能である.Reference
この問題について(デュアルチェーンテーブルの実装), 我々は、より多くの情報をここで見つけました https://velog.io/@lky9303/double-linked-list-구현テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol