def location (S, low, high):
if (low > high):
return 0
else:
mid = (low + high) // 2
if (x == S[mid]):
return mid
elif (x < S[mid]):
return location(S, low, mid - 1)
else:
return location(S, mid + 1, high)
merge sort도 Divide and Conquer로 풀어보쟈 😎
def mergesort (S):
n = len(S)
if (n <= 1):
return S
else:
mid = n // 2
U = mergesort(S[0 : mid])
V = mergesort(S[mid : n])
return merge(U, V)
def merge(U, V):
S = []
i = j = 0
while (i < len(U) and j < len(V)):
if (U[i] < V[j]):
S.append(U[i])
i += 1
else:
S.append(V[j])
j += 1
if (i < len(U)):
S += U[i : len(U)]
else:
S += V[j : len(V)]
return S
위 소스코드는 정렬은 됨 하지만 입력리스트인 S 외에 리스트 U 와 V 두개나 더 사용해야 한다.
따라서 메모리 사용에 비효율성이 있음,, 이거 어떻게 개선할까?
리스트 더 쓰지 말고 안에서 정렬해보자
def mergesort2 (S, low, high):
if (low < high):
mid = (low + high) // 2
mergesort2(S, low, mid)
mergesort2(S, mid + 1, high)
merge2(S, low, mid, high)
def merge2 (S, low, mid, high):
U = []
i = low
j = mid + 1
while (i <= mid and j <= high):
if (S[i] < S[j]):
U.append(S[i])
i += 1
else:
U.append(S[j])
j += 1
if (i <= mid):
U += S[i : mid + 1]
else:
U += S[j : high + 1]
for k in range(low, high + 1):
S[k] = U[k - low]
def quicksort (S, low, high):
if (high > low):
pivotpoint = partition(S, low, high)
quicksort(S, low, pivotpoint - 1)
quicksort(S, pivotpoint + 1, high)
여기서 문제, 어떻게 partition할 것인가??
15를 기준으로 작으면 왼쪽, 크면 오른쪽으로 분할
계속 첫번째 원소를 기준으로 배열을 분할한다
def partition (S, low, high):
pivotitem = S[low]
j = low
for i in range(low + 1, high + 1):
if (S[i] < pivotitem):
j += 1;
S[i], S[j] = S[j], S[i] # swap
pivotpoint = j
S[low], S[pivotpoint] = S[pivotpoint], S[low] # swap
return pivotpoint
partition()함수를 다르게 구현해볼 수 없을까~~
S = [26, 5, 37, 1, 61, 11, 59, 15, 48, 19]
[26, 5, 37, 1, 61, 11, 59, 15, 48, 19]: 2, 9
[26, 5, 19, 1, 61, 11, 59, 15, 48, 37]: 4, 7
[26, 5, 19, 1, 15, 11, 59, 61, 48, 37]: 6, 5
[11, 5, 19, 1, 15, 26, 59, 61, 48, 37]
앞 뒤에서 맨 앞 원소인 pivotpoint보다 큰지/작은지 한꺼번에 비교하자
끝난 후 중간에 있는 원소를 pivotpoint로 바꿈
def partition2 (S, low, high):
pivotitem = S[low]
i = low + 1
j = high
while (i <= j):
while (S[i] < pivotitem):
i += 1
while (S[j] > pivotitem):
j -= 1
if (i < j):
S[i], S[j] = S[j], S[i] # swap
pivotpoint = j
S[low], S[pivotpoint] = S[pivotpoint], S[low] # swap
return pivotpoint
i로 왼쪽부터 pivot item보다 큰 원소가 나올 때 까지 전진
j로 오른쪽부터 pivot item보다 작은 원소가 나올 때 까지 전진
만약 j가 i보다 오른쪽에 있다면 둘을 swap
(왜냐하면 오른쪽에 작은값 왼쪽에 큰 값 둘거니까)
def quicksort2 (S, low, high):
if (high > low):
pivotpoint = partition2(S, low, high)
quicksort2(S, low, pivotpoint - 1)
quicksort2(S, pivotpoint + 1, high)
래 퍼 에요 ??