使用第一个元素作为枢轴进行快速排序[关闭]

Posted

技术标签:

【中文标题】使用第一个元素作为枢轴进行快速排序[关闭]【英文标题】: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);
   

   

【问题讨论】:

也许尝试使用您的调试器? 至少提供堆栈跟踪。 缩进代码并删除不必要的代码。 【参考方案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);
    
  

  

【讨论】:

以上是关于使用第一个元素作为枢轴进行快速排序[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

快速排序

Java实现快速排序

算法知识详解快速排序算法

快速排序

算法:快速排序

您如何在中间位置实现枢轴快速排序,这种变化称为啥? [关闭]