📜  在QuickSort中Hoare的vs Lomuto分区方案(1)

📅  最后修改于: 2023-12-03 15:07:56.283000             🧑  作者: Mango

在QuickSort中Hoare的vs Lomuto分区方案

在QuickSort算法中,分区方案是关键步骤之一。Hoare和Lomuto是两种经典的分区方案,它们分别由Tony Hoare和Nicolas Lomuto在20世纪60年代提出。虽然它们都能够正确地对数组进行排序,但它们的表现却略有不同,这在某些情况下可能会导致性能上的差异。

Hoare分区方案

Hoare分区方案是这样实现的:首先选择一个pivot元素(常常是数组的最后一个元素),然后定义两个指针,一个指向数组的第一个元素,一个指向数组的最后一个元素。指针向中间移动,不断交换它们所指向的元素,直至左边的指针遇到了一个大于等于pivot的元素,右边的指针遇到了一个小于等于pivot的元素。这时,交换这两个元素,并重复这个过程,直至两个指针相遇。最后,把pivot元素和指针相遇的位置交换。

def partition(arr, low, high):
    pivot = arr[high]
    i = low - 1
    j = high + 1
    while True:
        while True:
            i += 1
            if arr[i] >= pivot:
                break
        while True:
            j -= 1
            if arr[j] <= pivot:
                break
        if i >= j:
            return j
        arr[i], arr[j] = arr[j], arr[i]

上面的代码使用了两个内层循环来遍历数组,这是Hoare方案的特点。注意,当两个指针都停止移动时,需要检查它们是否相遇。

Lomuto分区方案

Lomuto分区方案相对于Hoare分区方案要简单一些。它也是先选择一个pivot元素,然后定义两个指针,一个指向数组的第一个元素,一个从第一个元素开始遍历数组,如果找到一个小于等于pivot的元素,就把它与左指针所指的元素交换,并将左指针向右移动一个位置。最后,把pivot元素移到左指针的位置上。

def partition(arr, low, high):
    pivot = arr[high]
    i = low - 1
    for j in range(low, high):
        if arr[j] <= pivot:
            i += 1
            arr[i], arr[j] = arr[j], arr[i]
    arr[i+1], arr[high] = arr[high], arr[i+1]
    return i+1

上面的代码只有一个内层循环,它比Hoare方案要简单一些。注意,当找到小于等于pivot的元素时,左指针需要向右移动。

总结

在大多数情况下,这两个分区方案的效果差不多。但在一些特殊的情况下,它们的表现可能有所不同。例如,当数组中包含重复元素时,Hoare分区方案可能比Lomuto分区方案更优。此外,Hoare分区方案在某些最坏情况下可能会陷入无限循环,尽管这种情况在实际中很少见到。

所以,这两种分区方案都是值得掌握的,我们可以根据实际情况来选择哪种方案更适用。