n개의 서로 다른 수가 주어졌을 때, 이들을 이동하여 점점 커지게, 또는 점점 작아지게 만드는 문제.
-> 한 문제를 풀기 위해서 여러가지 방법이 가능
-> 방법마다 특징이 다름
-> 기본적인 문제이면서, 실생활에 자주 쓰임
-> 시간 복잡도, 최적성에 대해서 증명이 쉬움(당장은 이해가 제대로 안되도 괜찮음)
-> 이후 예제에서는, 정수를 오름차순으로 정렬하는 문제를 풀기로 함.
반론
-> 정렬은 다 남들이 짜놓은 코드가 있는데?
대응
-> 자동차 운전 면허에서 법규 구조는 왜 배우나?
-> 컴퓨터의 구조, 문제 해결의 원리를 이해하는 것은 중요하며, 정렬이라는 문제의 예를 통해서 이를 배운다.
-> 원리를 이해하면 풀고자 하는 문제에 적합한 답을 낼 수 있다.
-> 그렇지만, 남이 짜 놓은 코드를 정확하게 이용할 수 있는 것도 중요하다!
당연한거 아닌가요?
-> C에서 배열이라면 당연함.
-> 당연하지 않은 경우가 있음. 만약 데이터가 HDD에 있다면? 메인메모리에 비해 HDD, SSD는 느림.
-> 어떤 데이터를 가져오는데는 시간이 거의 안걸리지만, 또 다른 데이터를 가져오는데는 엄청난 시간이 걸릴 수 있다.
-> Big Data에서는 당연한 가정이 안통한다.
-> 앞으로 알고리즘에서 다루는 모든 문제는, 데이터가 메인 메모리에 저장되어 있다고 가정함.
정확성은 보이기 쉽다.
-> 제일 큰 원소가 제일 뒤.
-> 그 다음 큰 원소가 그 앞
시간 복잡도
-> 처음 가장 큰 원소를 구할 때 n-1번 비교
-> 두번째 큰 원소를 구할 때 n-2번 비교
-> (n-1) + (n-2) + … + 1 = n(n-1)/2 = Θ(n2)
-> 입력과 무관하게, n개의 값을 정렬할 때 항상 똑같은 횟수의 비교를 수행함
def bubblesort(L):
result = list(L)
for x in range(len(result)-1):
for y in range(len(result)-x-1):
if (result[y] > result[y+1]):
result[y], result[y+1] = result[y+1], result[y]
return result
>>> A = list(range(20))
>>> import random
>>> random.shuffle(A)
>>> bubblesort(A)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
def insertsort(L):
temp = list(L)
result = []
while (len(temp) > 0):
m = temp.pop(0)
result.append(m)
for i in range(1,len(result))[::-1]:
#포문에서 i를 거꾸로 세주는 것.
if (result[i] < result[i-1]):
result[i], result[i-1] = result[i-1], result[i]
else:
break
return result
>>> A = range(20)
>>> import random
>>> random.shuffle(A)
>>> insertsort(A)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
가장 좋을 때: 이미 오른차순으로 정렬되어 있을 때
-> 정렬된부분에 원소를 넣을 때마다, 비교를 한번만 하면 됨.
-> 총 n-1번 = Θ(n)
최악의 경우: 역순으로 정렬된 수들을 정렬할 때
i번째 위치의 원소를 정렬된 부분에 추가할 때 (즉, 이미 정렬된 부분에 i-1개의 원소가 있을 때) i-1개의 원소와 모두 비교
i=2, 3, ... , n이므로 1 + 2 + ... + n-1 = n(n-1)/2 = Θ(n2)
def merge(A, B):
if (len(A) == 0):
return B
if (len(B) == 0):
return A
if (A[0] < B[0]):
return [A[0]] + merge(A[1:], B)
#A[1:] 이거 때문에 A가 하나씩 계속 감소하는 것을 알 수 있음
else:
return [B[0]] + merge(A, B[1:])
def mergesort(L):
if (len(L) == 1):
return L
return merge(mergesort(L[:int(len(L)/2)]), mergesort(L[int(len(L)/2):]))