Hoare分区算法的解释

时间:2012-09-22 15:02:53

标签: python partitioning hoare-logic

根据许多网站提供的伪代码,我编写了这个Hoare分区算法,该算法采用一个数组,子数组的起始和结束索引根据给定的数据块进行分区。它工作正常,但有人可以解释逻辑,它是如何做它做的?这是'代码:

def hoare(arr,start,end):
     pivot = 4
     i,j = start,end
     while i < j:
        while i < j and arr[i] <= pivot:
            i += 1
        while j >= i and arr[j] > pivot:
            j -= 1
        if i < j:
            arr[i],arr[j] = arr[j],arr[i]
     return j    

还有另一种分区变体,即Lomuto算法。它做了类似的事情,虽然因为我首先不了解Hoare算法,所以我无法发现差异。任何人都可以解释算法中发生了什么,在哪种情况下哪一个能提供更好的性能?

2 个答案:

答案 0 :(得分:2)

我建议使用一副牌和两个棋子/硬币来模拟这个,以表示ij。基本上,算法同时完成这两件事:

  • 查找,其中应该将数组拆分为在此位置的左侧和右侧具有正确数量的“桶”。这是通过在分区的“中间”会议中ij的值来完成的。
  • 将数组元素移动到左侧或中间的右侧,具体取决于它们是否小于枢轴。

这意味着,i可以随时位于其中间或左侧。对j来说恰恰相反。知道了这一点,我们可以看到while循环所做的是找到一个位于中间左侧但应位于右侧的元素,反之亦然。也就是说,找到错误的一半中的两个元素。然后交换这些。

ij在中间相遇时,左侧会有while跳过的元素,因为它们小于pivot;或者从另一侧交换的元素,因此也小于pivot。 (反之亦然,中间的元素。)

可能的混淆源是可以认为从零开始的数组索引指向一个元素,或指向两个元素之间的。例如。索引0基本上意味着“在'第0个'和数组中的第一个元素之间”,当你访问一个元素时,你将跟随这个位置 - 使{ {1}}导致直观地数组的第一个元素。

答案 1 :(得分:0)

HoareLamuto都是分区算法。分区算法在数组中移动数据,以便小于某个元素的所有内容都在一侧结束,而一切元素在另一侧结束。这可用于快速排序数组或查找中位数。

Hoare的工作原理是将两个边界向中间移动,一个从左边移动,一个从右边移动。以下步骤在循环中完成:

  1. 左边界移动,直到达到比所选元素更大的值。
  2. 右边界移动,直到达到小于所选元素的东西。
  3. 如果没有交叉边界,则交换两者。
  4. 重复此过程,直到边界在中间相遇。结果是一个分区,左侧的所有内容都较少,而右侧的内容则较大。

    Lomuto是一个类似的过程,但只使用一个边界(通常从左边向上)。这使得它更容易实现,但速度稍慢(具有相同渐近复杂度的较大常数项)。