루비로 퀵 정렬 알고리즘 구현하기

이 포스트는 루비로 퀵 정렬 알고리즘을 구현한 포스트입니다.

필자의 티스토리 블로그에도 퀵 정렬 알고리즘을 구현한 포스트가 있지만 여기서는 조금 개량한 코드를 서술합니다.

def quick_sort(a, desc = false , randompivot = true)
	return a if a.length <= 1    # only 2 or more
	begin
		pivot = (a.max + a.min) / 2
	rescue
		pivot = a[randompivot ? rand(a.length) : a.length / 2]
	end
	less = Array.new       # less than pivot
	equal = Array.new      # equal to pivot
	greater = Array.new    # greater than pivot
	a.each do |x|
		less    << x if x < pivot
		equal   << x if x == pivot
		greater << x if x > pivot
	end
	# recursion
	if desc
		return quick_sort(greater, true, randompivot) + equal + quick_sort(less, true, randompivot)
	else
		return quick_sort(less, false, randompivot) + equal + quick_sort(greater, false, randompivot)
	end
end

파이썬으로 퀵 정렬 알고리즘 구현하기 포스트에서 구현한 알고리즘과 구조가 같습니다.

2번 줄에서 배열 크기를 검사합니다. 배열 크기가 1 이하일 경우 그냥 그 배열을 돌려주고 2 이상일 경우 다음 코드로 갑니다. 배열을 쪼개면서 재귀하는 특성상 배열 크기가 1 이하일 때 재귀를 멈춰야 하므로 필수로 넣어야 하는 부분입니다.

3번 줄부터 7번 줄까지가 기준값 잡는 코드입니다. 4번 줄은 배열의 최댓값과 최솟값의 중간값으로 기준값을 잡는 코드입니다. 만약 수치배열이 아닐 경우 오류가 일어나므로 이 때는 예외처리로 6번 줄로 넘어갑니다. 6번 줄에서는 기준값을 랜덤으로 잡거나 배열의 중간 값으로 잡습니다.

8번 줄부터 10번 줄까지는 기준값보다 작은 값, 기준값과 같은 값, 기준값보다 큰 값이 각각 들어갈 배열을 선언합니다.

11번 줄부터 15번 줄까지가 배열의 크기만큼 반복하는 반복문입니다. 각 배열의 원소를 하나씩 추출해서 그 값을 기준값과 비교한 다음 맞는 배열에 대입합니다.

17번 줄부터 21번 줄까지는 기준값보다 작은 값 배열과 큰 값 배열에 대해 재귀호출하면서 작은 값, 같은 값, 큰 값 배열을 합친 배열을 돌려줍니다. 만약 내림차순 옵션을 true로 주었다면 큰 값 – 같은 값 – 작은 값 순서대로 합치고 그 외에는 당연히 작은 값 – 같은 값 – 큰 값 순서대로 합칩니다.

이제 이 함수를 실험해 봅시다.

arr = [7, 1, 4, 6, 10, 2, 14, 16, 13, 11, 15, 9, 12, 5, 8, 3]
puts sprintf("  Unsorted: %s", arr)
puts sprintf(" Ascending: %s", quick_sort(arr) )
puts sprintf("Descending: %s", quick_sort(arr, true) )

정렬되지 않은 배열을 세팅한 다음 정렬 함수를 오름차순과 내림차순으로 실행해 보면,

  Unsorted: [7, 1, 4, 6, 10, 2, 14, 16, 13, 11, 15, 9, 12, 5, 8, 3]
 Ascending: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
Descending: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

정렬된 배열이 출력됩니다.

이와 같이 루비에서도 퀵 정렬 알고리즘을 구현해 볼 수 있습니다.

답글 남기기

이메일 주소는 공개되지 않습니다.