정렬은 이진 탐색*을 가능하게 하고, 데이터를 조금 더 효율적으로 탐색할 수 있게 만든다.
배열의 앞부분과 뒷부분의 두 그룹으로 나누어 각각 정렬한 후 병합하는 작업을 반복하는 알고리즘
# 병합정렬할 배열은 각각 이미 정렬됐다고 가정
array_a = [1, 2, 3, 5]
array_b = [4, 6, 7, 8]
def merge(array1, array2):
array_c = [] # 두 배열을 정렬하면서 새롭게 담을 배열
array1_index = 0
array2_index = 0
# 두 배열의 전체 요소를 전부 담을 때까지
while array1_index < len(array1) and array2_index < len(array2):
if array1[array1_index] < array2[array2_index]:
array_c.append(array1[array1_index])
array1_index += 1
else:
array_c.append(array2[array2_index])
array2_index += 1
# 만약 한 배열에서 모든 요소를 새로운 배열에 다 담았다면
# 비교를 하지 않고, 나머지 배열의 모든 요소를 새로운 배열에 담는다.
if array1_index == len(array1):
while array2_index < len(array2):
array_c.append(array2[array2_index])
array2_index += 1
if array2_index == len(array2):
while array1_index < len(array1):
array_c.append(array1[array1_index])
array1_index += 1
return array_c
print(merge(array_a, array_b))
# 이번에는 정렬되지 않은 전체 코드
array = [5, 3, 2, 1, 6, 8, 7, 4]
# 재귀 함수 형태로 문제를 분리한다.
def merge_sort(array):
# 탈출 조건: mergeSort하는 요소가 1개가 될 때까지
if len(array) <= 1:
return array
mid = len(array) // 2
left_array = merge_sort(array[:mid])
right_array = merge_sort(array[mid:])
return merge(left_array, right_array)
# 앞의 병합정렬 merge와 동일
def merge(array1, array2):
result = []
array1_index = 0
array2_index = 0
while array1_index < len(array1) and array2_index < len(array2):
if array1[array1_index] < array2[array2_index]:
result.append(array1[array1_index])
array1_index += 1
else:
result.append(array2[array2_index])
array2_index += 1
if array1_index == len(array1):
while array2_index < len(array2):
result.append(array2[array2_index])
array2_index += 1
if array2_index == len(array2):
while array1_index < len(array1):
result.append(array1[array1_index])
array1_index += 1
return result
print(merge_sort(array))
merge와 mergeSort의 경우 면접에서 직접 구현해보라는 경우도 있다.
https://www.acmicpc.net/problem/24060
https://www.acmicpc.net/problem/24061
https://www.acmicpc.net/problem/24062
한쪽 끝으로만 자료를 넣고 뺼 수 있는 자료 구조
Last In First Out LIFO 늦게 들어간 애가 빨리 나온다
ex. Ctrl+Z
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Stack:
def __init__(self):
self.head = None
def push(self, value):
"""
node = self.head
while node.next is None:
node = node.next
node.next = value
"""
new_head = Node(value)
new_head.next = self.head
self.head = new_head
# pop 기능 구현
def pop(self):
if self.is_empty():
return "Stack is Empty"
delete_head = self.head
self.head = self.head.next
return delete_head
def peek(self):
if self.is_empty():
return "Stack is Empty"
return self.head.data
# isEmpty 기능 구현
def is_empty(self):
return self.head is None
stack = Stack()
stack.push(3) # 3
print(stack.peek()) # >> 3
stack.push(4) # 4 - 3
print(stack.peek()) # >> 4
print(stack.pop().data) # >> 4
print(stack.peek()) # >> 3
print(stack.is_empty()) # >> False
import queue
data_queue = queue.LifoQueue()
# push()와 동일
data_queue.put(1) # 1
data_queue.put(2) # 2 - 1
data_queue.put(3) # 3 - 2 - 1
# pop()과 동일
data_queue.get() # >> 3
data_queue.get() # >> 2
https://www.acmicpc.net/problem/1874
https://www.acmicpc.net/problem/10828