단방향 연결 리스트
class Node:
def __init__(self, key=None):
self.key = key
self.next = None
def __str__(self):
return str(self.key)
class SinglyLinkedList:
def __init__(self):
self.head_node = Node()
self.size = 0
def __len__(self):
return self.size
def __iter__(self):
v: Node = self.head_node
while v is not None:
yield v
v = v.next
def search_by_key(self, key):
if len(self) == 0: return None
v: Node = self.head_node
while v is not None:
if v.key == key:
return v
v = v.next
return None
def search_by_index(self, index):
if len(self) == 0 or index < 0 or len(self) < index:
return None
i = 0
v: Node = self.head_node
while i != index:
v = v.next
i += 1
return v
def push_front(self, key):
new_node = Node(key)
new_node.next = self.head_node
self.head_node = new_node
self.size += 1
def push_back(self, key):
new_node = Node(key)
if len(self) == 0:
self.head_node = new_node
else:
tail: Node = self.head_node
while tail.next is not None:
tail = tail.next
tail.next = new_node
self.size += 1
def pop_front(self):
if len(self) == 0:
return None
target: Node = self.head_node
self.head_node = target.next
self.size -= 1
key = target.key
del target
return key
def pop_back(self):
if len(self) == 0:
return None
prev: Node = None
tail: Node = self.head_node
while tail.next is not None:
prev, tail = tail, tail.next
if len(self) == 1:
self.head_node = None
else:
prev.next = None
self.size -= 1
key = tail.key
del tail
return key
def insert(self, index, key):
if len(self) == 0 or index < 0 or len(self) < index:
return None
new_node = Node(key)
i = 0
prev: Node = None
target: Node = self.head_node
while i != index:
prev, target = target, target.next
i += 1
prev.next = new_node
new_node.next = target
self.size += 1
def remove(self, index):
if len(self) == 0 or index < 0 or len(self) < index:
return None
i = 0
prev: Node = None
target: Node = self.head_node
while i != index:
prev, target = target, target.next
i += 1
prev.next = target.next
key = target.key
self.size -= 1
del target
return key
ll = SinglyLinkedList()
for i in range(10):
ll.push_back(i)
print('INIT: ')
for v in ll:
print(f'{v}', end=' ')
print()
popped = ll.pop_back()
print(f'popped: {popped}')
searched = ll.search_by_index(2)
print(f'search_by_index - 2: {searched}')
searched = ll.search_by_key(4)
print(f'search_by_key - 4: {searched}')
removed = ll.remove(2)
print(f'removed - 2: {removed}')
ll.push_front(100)
print('PUSH-F: ')
for v in ll:
print(f'{v}', end=' ')
print()
ll.insert(100, 3)
print('INSERT: ')
for v in ll:
print(f'{v}', end=' ')
print()
양방향 연결 리스트
class Node:
def __init__(self, key=None):
self.key = key
self.prev, self.next = self, self
def __str__(self):
return str(self.key)
class CircularDoublyLinkedList:
def __init__(self):
self.head_node = Node()
self.size = 0
def __len__(self):
return self.size
def __iter__(self):
if len(self) == 0:
return
v = self.head_node.next
while v is not self.head_node:
yield v
v = v.next
def splice_list(self, a: Node, b: Node, x: Node):
a_prev, b_next, x_next = a.prev, b.next, x.next
a_prev.next = b_next
b_next.prev = a_prev
x.next = a
a.prev = x
b.next = x_next
x_next.prev = b
def search_by_key(self, key):
if len(self) == 0:
return None
v = self.head_node.next
while v is not self.head_node:
if v.key == key:
return v
v = v.next
return None
def search_by_index(self, index):
if len(self) == 0 or index < 0 or len(self) < index:
return None
i = 0
v = self.head_node.next
while i != index:
v = v.next
i += 1
return v
def move_after(self, a, x):
self.splice_list(a, a, x)
def move_before(self, a, x):
self.splice_list(a, a, x.prev)
def insert_after(self, key, x):
self.move_after(Node(key), x)
self.size += 1
def insert_before(self, key, x):
self.move_before(Node(key), x)
self.size += 1
def insert_using_index(self, index, key):
target = self.search_by_index(index)
self.insert_before(key, target)
def push_front(self, key):
self.insert_after(key, self.head_node)
def push_back(self, key):
self.insert_before(key, self.head_node)
def remove(self, x: Node):
if x is None or x == self.head_node:
return None
x_prev, x_next = x.prev, x.next
x_prev.next = x_next
x_next.prev = x_prev
key = x.key
self.size -= 1
del x
return key
def pop_front(self):
if len(self) == 0:
return None
return self.remove(self.head_node.next)
def pop_back(self):
if len(self) == 0:
return None
return self.remove(self.head_node.prev)
def remove_using_index(self, index):
target = self.search_by_index(index)
return self.remove(target)
ll = CircularDoublyLinkedList()
for i in range(10):
ll.push_back(i)
print('INIT:')
for v in ll:
print(f'{v}', end=' ')
print()
print(f'POP_FRONT: {ll.pop_front()}')
for v in ll:
print(f'{v}', end=' ')
print()
print(f'REMOVE_USING_INDEX: {ll.remove_using_index(3)}')
for v in ll:
print(f'{v}', end=' ')
print()
searched = ll.search_by_key(3)
print(f'SEARCH_KEY: {searched}')
searched = ll.search_by_index(7)
print(f'SEARCH_INDEX: {searched}')