数组比较太多 - 就地快速排序

时间:2021-04-20 18:54:03

标签: python quicksort

我实现了使用数组中间作为枢轴的就地快速排序。 我有一些需要完成的测试用例,但是我的代码似乎运行了很多比较。 对于数组列表:

[10, 4, 33, 44, 17, 20, 3, 2, 9, 82, 38, 67, 55, 11, 32, 23, 19, 7, 6, 14, 29, 10, 10]

我应该得到 142 个比较,但我得到了 196 个。

这是我的代码:

comparisons = 0

def addComparison() -> bool:
    global comparisons
    comparisons += 1
    return True

def quicksort(arr_list: list, lower_bound: int, upper_bound: int) -> list:
    if upper_bound > lower_bound:
        index = split_arr(arr_list, lower_bound, upper_bound)
        quicksort(arr_list, lower_bound, index)
        quicksort(arr_list, index+1, upper_bound)
    addComparison()

def split_arr(arr_list: list, lower_bound: int, upper_bound: int) -> int:
    global comparisons
    pivot_index = (lower_bound + upper_bound) // 2
    pivot_elem  = arr_list[pivot_index]

    while lower_bound <= upper_bound:

        left = lower_bound
        while addComparison() and arr_list[left] < pivot_elem:
            left += 1
        
        right = upper_bound
        while addComparison() and arr_list[right] > pivot_elem:
            right -= 1
        
        if left < right:
            arr_list[left], arr_list[right] = arr_list[right], arr_list[left]
            lower_bound = left  + 1
            upper_bound = right - 1
        else:
            return right
    return upper_bound

unsorted_list = [10, 4, 33, 44, 17, 20, 3, 2, 9, 82, 38, 67, 55, 11, 32, 23, 19, 7, 6, 14, 29, 10, 10]

quicksort(unsorted_list, 0, len(unsorted_list) - 1)

assert comparisons == 142

1 个答案:

答案 0 :(得分:1)

您实施的分区方案与您的教师不同,这将改变特定数据集的实际比较次数。

您的讲师似乎已经实施了基本的“以最后一项为中心”分区方案——通过将中间项交换到最后一项而略作修改,没有进行比较。我用那个算法在那个数据集上得到了 142。

使用 https://en.wikipedia.org/wiki/Quicksort 中的术语,您实现了 Hoare 分区方案,但您应该使用 Lomuto(这可能在课程中已涵盖)。

我不想发太多,但如果我是对的,那么
您的代码使用了 195 次比较和 29 次交换,并且
教师的代码使用了 142 次比较和 87 次交换。

相关问题