【问题标题】:Quick Sort using first element as pivot [closed]使用第一个元素作为枢轴进行快速排序[关闭]
【发布时间】:2014-10-25 20:28:56
【问题描述】:

我通过选择第一个元素作为枢轴来实现快速排序。它适用于一般测试用例,但考虑数组反向排序的情况,例如 5 4 3 2 1。我知道它在哪里引发运行时错误。但我无法正确修复它。第一个元素作为枢轴的实现是否正确?请提出修改建议。

 public static void quicksort(int low,int high)
  {

   if(low<high) 
   {
    int temp=0;
    int pivot=a[low];                     
    int large_index=low+1;
    int small_index=high;

    while(large_index<=small_index)
    {
      while(a[small_index]>pivot)
      small_index--;

      while(a[large_index]<pivot) 
      large_index++; 

      if(large_index<=small_index)
       {
       temp = a[large_index];
       a[large_index]= a[small_index];
       a[small_index]= temp;
       large_index++;
       small_index--;
      }
     }

     temp = a[small_index];
     a[small_index]= a[low];
     a[low]= temp;


    quicksort(low,small_index-1);
    quicksort(small_index+1,high);
   }

   }

【问题讨论】:

  • 也许尝试使用您的调试器?
  • 至少提供堆栈跟踪。
  • 缩进代码并删除不必要的代码。

标签: java algorithm pivot quicksort divide-and-conquer


【解决方案1】:

存在多个缺陷:

a) 循环外不必要的交换

temp = a[small_index];一个[小索引]=一个[低]; a[低]=温度;

b) large_index 初始化不当。

c) 调用递归函数而不检查 small_index 和 large_index。

我已经改正了,

现在函数看起来像:

if (low < high) {
            int temp = 0;
            int pivot = a[low];
            int large_index = low;
            int small_index = high;

            while (large_index <= small_index) {
                while (a[small_index] > pivot)
                    small_index--;

                while (a[large_index] < pivot)
                    large_index++;

                if (large_index <= small_index) {
                    temp = a[large_index];
                    a[large_index] = a[small_index];
                    a[small_index] = temp;
                    large_index++;
                    small_index--;
                }
            }

            if(low < small_index)
            {
                quicksort(low, small_index);
            }
            if(large_index < high)
            {
                quicksort(large_index, high);
            }
        }

现在,观察您的代码中的变量:(除非输入未排序,否则您的代码将在任何给定输入的最终迭代中失败)

考虑输入 2,1

1st iteration:

pivot = 2
large_index = 1;
small_index = 1;


while1:
1<=1 -> true
    while2: 1>2 false.
    while3: 1<2 true. -> large_index++
                2nd time in while loop large_index =2 which is > the size of a.

导致 IndexArrayOutOfBounds。

这表明您对 large_index 的初始化是错误的。

应该是:large_index = low;而不是低+1;

希望这会有所帮助。

【讨论】:

  • 非常感谢。我找到了缺陷。
  • 能否请您解释一下为什么数组索引在 while (a[large_index]
  • 已更新我的答案 w.r.t 你的 cmets。
  • 赞成所有在定位缺陷之前解开和整理 Ankur 代码的工作。程序员从优秀的代码示例中学到的东西最多。
  • @BatScream 请看一下我用相同方法发布的编辑代码?
【解决方案2】:

以下循环在high 上方继续,当large_index 已经在枢轴上方开始并且恰好枢轴大于位于它之后的每个元素时:

while(a[large_index]<pivot) 
large_index++; 

当然,可能还有其他错误。

【讨论】:

  • 我明白了。这就是我收到运行时错误的原因。但如果把条件放在前。 while(a[large_index]
  • 那行不通。它仍然会抛出 5 4 3 2 1 的异常。
  • @AnkurChandra 至少提供堆栈跟踪的哪一部分你不明白吗?不是每个人都会尝试通读您未缩进的代码,或者用鹰眼轻易地发现您的问题。
  • 对不起 Luiggi 但我是这里的初学者。我将 Notepad++ 用于我的代码。你能告诉我生成堆栈跟踪的方法吗?提前致谢。
  • @AnkurChandra 堆栈跟踪是执行代码时出现在控制台中的长消息。对于初学者,我建议使用 Eclipse 或 IntelliJ Idea 之类的 IDE。当您获得更多经验时,请使用 Notepad++ 或其他文本编辑器。
【解决方案3】:

经过一些尝试,我能够制作快速排序功能,现在它工作正常。 @BatScream 我仍然在我的代码中使用了 small_index=low+1 。所以我猜这不是一个错误。而原始的快速排序算法就遵循这种机制。参考请观看普林斯顿大学教授罗伯特·塞奇威克关于快速排序的讲座。编辑后的快速排序算法如有缺陷请提醒。

public static void quicksort(int low,int high)
 {

   if(low<high) 
   {
    int temp=0;
    int pivot=a[low];                     
    int large_index=low+1;
    int small_index=high;

    while(large_index<small_index)
  {

     while(a[large_index]<pivot) {
     if(large_index==high) 
     break;
     large_index++; 
   } 

    while(a[small_index]>pivot) 
   {
     if(small_index==low) 
     break;
     small_index--; 
   }

   if(large_index<small_index) {
     temp = a[large_index];
     a[large_index]= a[small_index];
     a[small_index]= temp;
     large_index++;
     small_index--; 
    }
  }   

    if(a[small_index]<pivot) {                               
       temp = a[small_index];
       a[small_index]= a[low];
       a[low]= temp;
  }

     if(low<small_index)                                    //Recursively sort the left half.
    {
     quicksort(low,small_index-1);
    }

    if(high>small_index)                                    //Recursively sort the right half.
   {
    quicksort(small_index+1,high);
    }
  }

  }

【讨论】:

    猜你喜欢
    • 2022-11-15
    • 2016-03-29
    • 2012-12-20
    • 1970-01-01
    • 2021-11-28
    • 2019-11-23
    • 2011-01-19
    • 1970-01-01
    • 2011-08-31
    相关资源
    最近更新 更多