Java 我不确定我的快速选择方法有什么问题

Java 我不确定我的快速选择方法有什么问题,java,Java,因此,我尝试编写一个代码,使用快速排序在给定的输入整数数组中选择第k个最小元素,但由于某种原因,正如您在下面的代码中所看到的 public static int partition(int[] input, int first, int end) { int pivot = input[(first + end)/2]; int i = first - 1; int j = end + 1; while (true) { do {

因此,我尝试编写一个代码,使用
快速排序
在给定的输入
整数
数组中选择第k个最小元素,但由于某种原因,正如您在下面的代码中所看到的

public static int partition(int[] input, int first, int end) {
    int pivot = input[(first + end)/2];
    int i = first - 1;
    int j = end + 1;

    while (true) {

      do {
        i++;
      } while (input[i] < pivot);

      do {
        j--;
      } while (input[j] > pivot);

      if (i < j)
        swap(input, i, j);
      else
        return j;
    }
  }

  public static void swap(int[] input, int i, int j){
    int temp = input[i];
    input[i] = input[j];
    input[j] = temp;
  }

  public static int select(int[] input, int k){
    return mySelect(input, 0, input.length-1, k);
  }

  public static int mySelect(int[] input, int left, int right, int k){ 
    // If k is smaller than number of elements in array 
    if (k > 0 && k <= right - left + 1) { 

      int pos = partition(input, left, right); 

      if (pos - left == k - 1) 
        return input[pos]; 

      // If position is larger, recursive call on the left subarray 
      if (pos - left > k - 1)  
        return mySelect(input, left, pos-1, k); 

      // if smaller, recursive call on the right subarray 
      return mySelect(input, pos+1, right, k-pos+left-1); 
    } 

    System.out.println("Invalid k value");
    return Integer.MAX_VALUE; 
  }

public static void main(String[] args){
    test2 = new int[]{99, 44, 77, 22, 55, 66, 11, 88, 33};
    int[] test2 = new int[]{99, 44, 77, 22, 55, 66, 11, 88, 33};
    //testing for selecting kth min 
    System.out.println("The 1st smallest : " + select(test2, 1));
    System.out.println("The 2nd smallest : " + select(test2, 2));
    System.out.println("The 3rd smallest : " + select(test2, 3));
    System.out.println("The 4th smallest : " + select(test2, 4));
    System.out.println("The 6th smallest : " + select(test2, 6));
    System.out.println("The 9th smallest : " + select(test2, 9)); 
    }

publicstaticint分区(int[]input,int-first,int-end){
int pivot=输入[(第一个+结束)/2];
int i=第一个-1;
int j=结束+1;
while(true){
做{
i++;
}while(输入[i]pivot);
if(i0&&k k-1)
返回mySelect(输入,左侧,位置1,k);
//如果较小,则递归调用右侧子数组
返回mySelect(输入,pos+1,right,k-pos+left-1);
} 
System.out.println(“无效的k值”);
返回Integer.MAX_值;
}
公共静态void main(字符串[]args){
test2=newint[]{99,44,77,22,55,66,11,88,33};
int[]test2=新的int[]{99,44,77,22,55,66,11,88,33};
//选择kth最小值的测试
System.out.println(“最小的第一个:”+select(test2,1));
System.out.println(“第二个最小值:+select(test2,2));
System.out.println(“第三小:”+select(test2,3));
System.out.println(“第四个最小值:+select(test2,4));
System.out.println(“最小的第六个:”+select(test2,6));
System.out.println(“第九个最小值:+select(test2,9));
}
但是我的第一个最小元素显示为22,第二个最小元素返回11,而其他值为正常值。
有人能帮我找出我犯的错误吗?

您的代码中的问题在分区中。
do while
是罪魁祸首。您在检查条件之前正在更新位置,这导致了
最后一次
交换操作出现问题

更新你的方法到这个,你会很好去

public static int partition(int[] input, int first, int end) {
    int pivot = input[(first + end)/2];
    int i = first;
    int j = end;

    while (true) {

      while (input[i] < pivot) {
        i++;
      }

      while (input[j] > pivot) {
        j--;
      }

      if (i < j)
        swap(input, i, j);
      else
        return j;
    }
}
publicstaticint分区(int[]input,int-first,int-end){
int pivot=输入[(第一个+结束)/2];
int i=第一;
int j=结束;
while(true){
while(输入[i]pivot){
j--;
}
if(i
我在学习快速排序时编写了此代码。我犯的错误是没有意识到这一点

“left”和“right”是数组中的索引

“pivot”是存储在数组中的值之一

您可以研究我下面的代码,并确定您对算法的理解有何错误

public class QuickSort
{   
    public static void main(String[] args)
    {
        int[] nums = {1,5,9,2,7,8,4,2,5,8,9,12,35,21,34,22,1,45}; 

        quickSort(0,nums.length-1,nums);
        //print nums to see if sort is working as expected,omit printing in your case
        print(nums);
        //now you can write code to select kth smallest number from sorted nums here
    }

    /**
     * left and right are indices in array whereas
     * pivot is one of the values stored in array
     */
    static int partition(int left, int right , int pivot, int[] nums)
    {
        int leftIndex = left -1;
        int rightIndex = right;
        int temp = 0;
        while(true)
        {
            while( nums[++leftIndex] < pivot );
            while( rightIndex>0 && nums[--rightIndex] > pivot );

            if( leftIndex >= rightIndex ) break;
            else//swap value at leftIndex and rightIndex
            {
                temp = nums[leftIndex];
                nums[leftIndex]= nums[rightIndex];
                nums[rightIndex] = temp;
            }
        }

        //swap value at leftIndex and initial right index
        temp = nums[leftIndex];
        nums[leftIndex]= nums[right];
        nums[right] = temp;

        return leftIndex;
    }

    static void quickSort( int leftIndex , int rightIndex ,int[] nums)
    {
        if( rightIndex-leftIndex <= 0 ) return;
        else
        {
            int pivot = nums[rightIndex];
            int partitionIndex = partition(leftIndex, rightIndex , pivot,nums);
            quickSort(leftIndex,partitionIndex-1,nums);
            quickSort(partitionIndex+1,rightIndex,nums);
        }
    }

    static void print(int[] nums)
    {
        for( int i = 0 ; i < nums.length ; i++ )
        {
            System.out.print(nums[i]+", ");
        }
    }

}
公共类快速排序
{   
公共静态void main(字符串[]args)
{
int[]nums={1,5,9,2,7,8,4,2,5,8,9,12,35,21,34,22,1,45};
快速排序(0,nums.length-1,nums);
//打印NUM若要查看排序是否按预期工作,请在您的案例中省略打印
印刷品(nums);
//现在您可以在这里编写代码,从排序的num中选择第k个最小的数字
}
/**
*左和右是数组中的索引,而
*pivot是存储在数组中的值之一
*/
静态int分区(int left、int right、int pivot、int[]nums)
{
int leftIndex=left-1;
int rightIndex=右;
内部温度=0;
while(true)
{
while(nums[++leftIndex]0&&nums[--rightIndex]>pivot);
如果(leftIndex>=rightIndex)中断;
else//在leftIndex和rightIndex处交换值
{
temp=nums[leftIndex];
nums[leftIndex]=nums[rightIndex];
nums[rightIndex]=温度;
}
}
//交换左索引和初始右索引处的值
temp=nums[leftIndex];
nums[leftIndex]=nums[right];
nums[右]=温度;
返回左索引;
}
静态void快速排序(int-leftIndex、int-righindex、int[]nums)
{

如果(rightIndex leftIndex您对调试此代码做了什么?提示-您的
select
方法似乎不仅仅是
select
,它还作为一种副作用修改了数组并对其排序。如果您将代码更改为先对数组排序,仅一次,然后选择,则您更有可能找到问题的确切位置-为方法指定一个单独的职责,并为它们指定一个名称,以指示该方法的实际功能。