当前位置: 首页 > 知识库问答 >
问题:

重复轴值的Hoare划分算法

濮宇定
2023-03-14

以下是根据维基百科的霍尔分区算法。

来自维基百科的伪代码:

algorithm partition(A, lo, hi) is 
  // Pivot value
  pivot := A[ floor((hi + lo) / 2) ] // The value in the middle of the array

  // Left index
  i := lo - 1 

  // Right index
  j := hi + 1

  loop forever 
    // Move the left index to the right at least once and while the element at
    // the left index is less than the pivot
    do i := i + 1 while A[i] < pivot
    
    // Move the right index to the left at least once and while the element at
    // the right index is greater than the pivot
    do j := j - 1 while A[j] > pivot

    // If the indices crossed, return
    if i ≥ j then return j
    
    // Swap the elements at the left and right indices
    swap A[i] with A[j]

java实现:

public class Main
{
    public static void main(String[] args) {
        int[] arr = new int[] { 2, 1, 2, 4, 3 };
        Hoare.partition(arr, 0, 4);

        for (int x : arr) System.out.println(x);
    }
}

class Hoare
{
    private static void Swap(int[] array, int i, int j)
    {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
 

    public static int partition(int []arr, int low, int high)
    {
        int pivot = arr[(low + high) / 2]; // pivot is 2 for this case.
        // Expected out is:
        // 1 2 2 3 4
        // or
        // 1 2 2 4 3
        //
        // Actual output is:
        // 2 1 2 4 3
        // Since 3 and 4 are greater than 2, then the partitioning isn't working.

        int i = low - 1;
        int j = high + 1;
     
        while(true)
        {
            do {
                i++;
            }
            while (arr[i] < pivot);
            
            do {
                j--;
            }
            while (arr[j] > pivot);
            
            if (i >= j)
            {
                return j;
            }
            
            Swap(arr, i, j);
        }
    }
}

为什么输出错误(在代码注释中指出)?这是Hoare算法的已知限制吗?是我的实现还是维基百科的伪代码不正确?

共有1个答案

姬自强
2023-03-14

霍尔算法保证轴之前的所有元素小于或等于轴值,轴之后的所有元素大于或等于轴值。

这也意味着枢轴值位于最终排序数组中的正确索引处。这对快速排序算法很重要。

Hoare分区不保证所有等于透视值的元素都是连续的。这不是快速排序算法的要求,所以花费任何额外的计算能力来保证它是没有意义的。

换句话说,执行是正确的;结果是预期的;而且它可以在快速排序中正常工作。

 类似资料:
  • 我是新来的Laravel,我需要通过分组来计算值,例如,我有这些值 我需要计算列中有多少个1,我希望结果是男性:3,女性:2 我试过这种方法,但效果不理想

  • 假设我有这个数组: 我该如何让它做这样的事情呢 我不知道什么谷歌得到一个答案,因为我所有的结果都是不同的问题,因为我想这不是太常见的事情无论如何,任何和所有的帮助都将不胜感激:)

  • 我查阅了很多关于ValueError:cannot reindex from a duplicate axis([ValueError:cannot reindex from a duplicate axis'是什么意思?以及其他相关文章。我知道重复的行索引或列名可能会导致错误,但我仍然不能完全弄清楚到底是什么原因导致了我出现错误。 下面是我最擅长重现数据框架的精神,它确实会抛出错误。 以下是错误

  • 我正在处理一个数据管道在空气流,并不断运行到这个,我已经拍了我的头几天。 这是一个混乱的函数: 以下是AWS Cloudwatch日志的错误输出: 我已经运行了一些记录器,以了解该步骤中数据帧的输出,但我不知道问题点在哪里: 我在这些帖子中尝试了一切,但都没有成功: 错误:无法从重复轴重新索引 ValueError:不能从重复的轴重新索引是什么意思? 我也不完全明白为什么会发生这种情况。任何建议都

  • 问题内容: 我有以下json 我想计算重复的名字 重复计数3 不可重复的名字计数 非重复计数2 我试图计算存储桶的数量,但似乎计算所有存储桶是重复的还是非重复的 问题答案: 好吧,我在这里利用了几种聚合。以下是我使用过的列表。列表的顺序是聚合的执行顺序。 对于重复 术语汇总 统计数据桶汇总 对于非重复 术语汇总 桶选择器 (作为子集合) 总和桶选择器 汇总查询: 响应 注意,在上面的响应中,我们有

  • 我知道Java不支持运算符重载,但我看到您可以为Integer对象赋值,例如,使用运算符,而不是使用setter。 所以我想知道是否有可能将这种行为实现到任何类?