为什么这种类型在快速排序应用中是必需的

时间:2015-01-23 21:34:33

标签: java algorithm sorting quicksort

我试图理解quicksort应用程序中的代码来找到第k个最小元素。

以下是作者编写的代码

public class KthSmallest {
    public static void main(String[] args) {
        int[] test = {2,3,1,5,7,6,9};
        System.out.println("4th smallest is " + quick_select(test, 4, 0, test.length - 1));
    }
    private static int quick_select(int[] a, int k, int left, int right) {
         int pivot=findpivot(a,left,right);
         if(pivot==k-1){
              return a[pivot];
         }
         if(k-1<pivot){
              return quick_select(a, k, left, pivot-1);
          }
          else {
              return quick_select(a, k, pivot+1, right);
          }
        }
        private static int findpivot(int[] a, int left, int right) {
            int pivot = a[(left+right)/2];
            while(left<right){
                while(a[left]<pivot){
                    left++;
                }
                while(a[right]>pivot){
                    right--;
                }

                if(left<=right){
                    swap(a,left,right);
                    left++;
                    right--;
                }

            }
            return left;
        }

        private static void swap(int[] a, int i, int j) {
            int temp=a[i];
            a[i]=a[j];
            a[j]=temp;

        }


}

我试图了解此代码段在find pivot中的重要性

     if(left<=right){
                    swap(a,left,right);
                    left++;
                    right--;
        }

这就是你所知道的。左侧左侧的所有元素都小于枢轴。右边右边的所有元素都大于枢轴。有人可以解释为什么有必要交换,如果正确&gt; =左?

2 个答案:

答案 0 :(得分:1)

第一个循环向右移动left,直到找到大于枢轴的元素。第二个循环向左移动right,直到找到小于枢轴的元素。此时a[left]应该在枢轴之后移动,而a[right]应该在枢轴之前移动,if if会照顾它。

答案 1 :(得分:0)

  

任何人都可以用直觉解释为什么有必要交换if   对&gt; =左?

rightleft是索引 - 而不是项目本身(这可能是您混淆的原因)。如果枢轴“右”的数字小于枢轴,则它应移动到枢轴的左侧。

分别如果枢轴左侧的数字大于枢轴 - 它应该移动到(枢轴的)右侧。

一旦我们遇到两个这样的项目,我们使用if条件来确保我们在之前的循环中没有“走得太远”并且确实应该交换找到的数字,这个check - 测试索引left <= right否则没有理由进行交换(或继续运行...)。

注意:上一段中的说明显示我们不必检查if(left<=right) - 它足以检查if(left<right)