def swap(arr, i, j):
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
def bubble_sort(list) :
for i in range(list(len)):
for j in range(len(list)-i-1):
if list[j] > list[j+1]:
swap(list,j,j+1) #뒤에 오는 원소가 더 크도록 위치 교환
# 개선된 선택정렬
def select_sort(list) :
for i in range(len(list)):
min_idx = i
for j in range(i+1,len(list)):
if list[j] < list[min_idx]:
min_idx = j
swap(list,i,min_idx) # 버블정렬에서 사용된 swap 사용
def insert_sort(list):
for i in range(1,len(list)):
target = list[i] # 삽입할 원소
for j in range(i-1,-1,-1):
if list[j] > target :
list[j+1]=list[j]
else :
list[j+1] = target
def heapify(heap, index, heap_size):
largest = index
left_child_index = index*2
right_child_index = index*2+1
if (left_child_index < heap_size) and (heap[largest] > heap[left_child_index]) : #왼쪽 자식 노드가 존재하고, 부모 노드보다 작은 경우
largest = left_child_index
if (right_child_index < heap_size) and (heap[largest] > heap[right_child_index]) : #오른쪽 자식 노드가 존재하고, 부모 노드보다 작은 경우
largest = right_child_index
if index != largest :
heap[largest],heap[index] = heap[index],heap[largest] # 자식노드와 부모 노드를 교환한다.
heapify(heap, largest, heap_size) # 자식노드를 루트노드로 하는 힙에 대해서 heapify를 수행한다.
def heap_sort(list):
n = len(list)
# 1. 최소힙 구성
# 자식 노드를 갖는 마지막 노드부터 상향으로 heapify 진행한다.
# 마지막 노드부터 수행하지 않아도 된다.
for i in range(n//2-1,-1.-1):
heapify(list, i, n)
for i in range(n-1,0,-1):
list[i], list[1] = list[1], list[i] # 2. 루트 노드와 마지막 노드의 값을 교환한다.
heapify(list, 0, i) # 3. 나머지 배열에 대해 heapify 수행
def merge_two_array(list, left, mid, right):
temp_list=[]
current_index = left
left_index = left
right_index = mid +1
while (left_index <= mid) and (right_index <= right) :
if list[left_index] < list[right_index] :
temp_list[current_index] = list[left_index]
left_index += 1
else :
"""
not stable인 이유 :
두 배열의 비교 대상이 동일한 원소인 경우,
뒤쪽 배열에 위치한 원소를 먼저 옮기기 때문이다.
"""
temp_list[current_index] = list[right_index]
right_index += 1
current_index += 1
#왼쪽 원소 완전히 옮기기
while (left_index <= mid) :
temp_list[current_index] = list[left_index]
left += 1
current_index += 1
#오른쪽 원소 완전히 옮기기
while (mid+1 <= righ) :
temp_list[current_index] = list[right]
right += 1
current_index += 1
#결과 배열로 원소 옮기기
for i in range(len(list)):
list[i] = temp_list[i]
def merge_sort(list, left, right):
if left < right :
# 정렬 대상 분할하기
mid = (left+right)//2
merge_sort(list,left,mid)
merge_sort(list,mid+1,right)
# 정렬 대상 합치면서 정렬하기
merge_two_array(list,left,mid,right)
"""
윤성우의 열혈 자료구조 ver
- 분할하는 부분과 정렬하는 부분을 두 함수로 구분
"""
def partition(list,left,right):
low = left+1
high = right
while low <= high :
while (low <= right) and (list[low] <= list[left]) :
low += 1
while (left <= high) and (list[high] >= list[left]) :
high -= 1
if low < high :
swap(list,low,high)
swap(list, left, high)
return high
def quick_sort(list, left, right):
if left < right :
pivot = partition(list, left, right)
quick_sort(list,left, pivot-1)
quick_sort(list,pivot+1,right)
"""
일반적으로 많이 쓰이는 ver
- 하나의 함수 안에서 분할, 정렬을 모두 수행
- 피벗을 기준으로 세 배열로 나눈 후 이를 합치는 방법으로 정렬을 수행
"""
def quick_sort(list) :
if len(list) <= 1:
return list
pivot = list[0] # 배열의 중간값을 사용해도 됨
# 각각 피벗보다 크기가 작은, 같은, 큰, 원소를 저장하는 리스트를 의미함
less_list =[]
equal_list=[]
greater_list = []
for i in list :
if i > pivot :
greater_list.append(i)
elif i == pivot :
equal_list.append(i)
else:
less_list.append(i)
return quick_sort(less_list) + equal_list + quick_sort(greater_list)
(모든 정렬은 오름차순 기준으로 설명함.)