quick sort에서 효과적인 pivot을 구하는 방법?

  • re4lfl0w
    re4lfl0w
    • 현재 알고리즘은 단순히 제일 처음에 오는걸 pivot으로 하고 있는데요.
    • http://interactivepython.org/courselib/static/pythonds/SortSearch/TheQuickSort.html 를 보면 효과적으로 pivot을 구하는 방법을 적어 놨습니다.
    • 첫번째, 중간, 마지막 값을 체크해서 그 중간값을 선택한다고 하는데요.. 제가 코드를 짜기는 했는데 get_pivot()에서 잘 안되네요.. 3개 이상인 리스트의 pivot을 선택할 경우에서 잘 안되고 있습니다. 그래서 중복값인 31이 있을때 이게 제대로 정렬이 안됩니다. 이 함수를 어떻게 하면 잘 짤 수 있을까요?
    • 또 이것보다 좀 더 효과적으로 pivot을 구할 수 있는 방법은 없을까요?

    • source: quick sort

    # How efficient to get pivot?
    
    def get_pivot(array, left, right):
        # 현재 잘 안되고 있음
        if abs(left-right) > 2:
            mid = len(array) // 2
            first = 0
            last = len(array) - 1
    
            dic = {first: array[first],
                   mid: array[mid],
                   last: array[right]}
            min_ = array[first]
            max_ = array[last]
            for k, v in dic.items():
                if v < min_:
                    min_ = k
                if v > max_:
                    max_ = k
            pivot = [k for k, v in dic.items() if not dic[k] or not dic[k]][0]
            # print('')
        else:
            pivot = left
        pivot = left
        return pivot
    
    
    def partition(array, left, right):
        pivot = get_pivot(array, left, right)
        while True:
            while array[left] <= array[pivot]:
                left += 1
            while array[right] > array[pivot]:
                right -= 1
            if left < right:
                array[left], array[right] = array[right], array[left]
            else:
                break
        array[pivot], array[right] = array[right], array[pivot]
        return right
    
    
    def quicksort(array, begin=0, end=None):
        if end is None:
            end = len(array) - 1
        if begin >= end:
            return
        pivot = partition(array, begin, end)
        quicksort(array, begin, pivot-1)
        quicksort(array, pivot+1, end)
    
    
    array = [54,26,93,17,77,31,31,44,55,20]
    print(array)
    quicksort(array)
    print(array)
    # [17, 20, 26, 31, 31, 44, 54, 55, 77, 93]
    

    8년 전
1개의 댓글이 있습니다.
  • Being
    Being

    get_pivot 함수는 하루쯤 자고 일어나셔서(지금쯤이면) 다시 차근히 짜시면 될 것 같고요, pivot 선택에 대한 심도있는 논의는 https://en.wikipedia.org/wiki/Quicksort#Choice_of_pivot 를 참고하세요.


    8년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.