Given a set of N comparable elements, we want to find the Kth smallest element (K≤N) in the collection (it would be the overall smallest if K=1).
Use the partition method of the quick sort algorithm. Suppose it led to a partition of L and (N-1-L) elements. If L<K, I need to recur on only right side. Otherwise, I need to recur on only left side.
Note: Since we are using median of three method to find pivot. We do not need to check from left to right, just from left+1 to right-1. But when we do partition later, we are going to do ++i and --j before checking. Then if we only have two elements, the Array index will go out of bound(- or + twice). So we need to deal with this case separately.
/**************************
* The Kth smallest program
*
* Author: QT_pixy
* Date: Feb. 5, 07
**************************/

public class kthsmallest
{
public static <AnyType extends Comparable<? super AnyType>>
AnyType FindKthSmallest(AnyType [] A, int k)
{
return Find(A, 0, A.length - 1, k);
}
private static <AnyType extends Comparable<? super AnyType>>
AnyType Find(AnyType [] A, int left, int right, int k)
{
// checking base step
if(left == right)
return A[left];
// Since we are using median of three method to find pivot.
// We do not need to check from left to right, just from left+1 to right-1.
// But when we do partition later, we are going to do ++i and --j before checking.
// Then if we only have two elements, the Array index will go out of bound(- or + twice).
// So we need to deal with this case separately.
if(left + 1 == right)
{
if(A[left].compareTo(A[right]) > 0)
swapReferences(A, left, right);
if(left + 1 == k)
return A[left];
if(right + 1 == k)
return A[right];
}
AnyType pivot = median3(A, left, right);
int i = left, j = right - 1; // from left+1 to right - 1, since we use Median of three method,
// (since later we will ++i and --j)
// we do not need to worry about the first one and the last one.
for( ; ; )
{
while( A[++i].compareTo( pivot ) < 0 && i <= right - 1)
{
}
while( A[--j].compareTo( pivot ) > 0 && j > left)
{
}
if( i < j )
swapReferences( A, i, j );
else
break;
}
swapReferences( A, i, right - 1 ); // Restore pivot
if (i + 1 > k)
return Find(A, left, i - 1, k);
if (i + 1 < k)
return Find(A, i + 1, right, k);
else
return A[i];
}

// The median-of-three method
//
private static <AnyType extends Comparable<? super AnyType>>
AnyType median3 (AnyType[] A, int left, int right)
{
int center = (left + right) / 2;
if (A[center].compareTo(A[left]) < 0 )
swapReferences(A, left, center);
if (A[right].compareTo(A[left]) < 0)
swapReferences(A, left, right);
if (A[right].compareTo(A[center]) < 0)
swapReferences(A, right, center);

swapReferences(A, center, right - 1);
return A[right - 1];

}

private static <AnyType extends Comparable<? super AnyType>>
void swapReferences(AnyType [] A, int num1, int num2)
{
AnyType temp = A[num1];
A[num1] = A[num2];
A[num2] = temp;
}
}
This is the Main program which implement the routine above.
/**************************
* The Kth smallest program
*
* Author: QT_pixy
* Date: Feb. 5, 07
**************************/

import java.util.Scanner;

public class Main2
{
public static void main(String[] args)
{
Integer [] A = {23, 4, 42, 3, 13, 12};
//Integer [] A = {10, 2, 5, 23, 45, 22, 23, 4, 14, 70, 62, 3, 20, 15, 24};

// You should use larger arrays for testing your program.

Scanner input = new Scanner(System.in);

int k = input.nextInt();
while(k > 6 || k < 1)
{
System.out.println("Try again!");
k = input.nextInt();
}
Integer elem = kthsmallest.FindKthSmallest(A, k);
System.out.println(elem);
}
}
Use the partition method of the quick sort algorithm. Suppose it led to a partition of L and (N-1-L) elements. If L<K, I need to recur on only right side. Otherwise, I need to recur on only left side.
Note: Since we are using median of three method to find pivot. We do not need to check from left to right, just from left+1 to right-1. But when we do partition later, we are going to do ++i and --j before checking. Then if we only have two elements, the Array index will go out of bound(- or + twice). So we need to deal with this case separately.
/**************************
* The Kth smallest program
*
* Author: QT_pixy
* Date: Feb. 5, 07
**************************/
public class kthsmallest
{
public static <AnyType extends Comparable<? super AnyType>>
AnyType FindKthSmallest(AnyType [] A, int k)
{
return Find(A, 0, A.length - 1, k);
}
private static <AnyType extends Comparable<? super AnyType>>
AnyType Find(AnyType [] A, int left, int right, int k)
{
// checking base step
if(left == right)
return A[left];
// Since we are using median of three method to find pivot.
// We do not need to check from left to right, just from left+1 to right-1.
// But when we do partition later, we are going to do ++i and --j before checking.
// Then if we only have two elements, the Array index will go out of bound(- or + twice).
// So we need to deal with this case separately.
if(left + 1 == right)
{
if(A[left].compareTo(A[right]) > 0)
swapReferences(A, left, right);
if(left + 1 == k)
return A[left];
if(right + 1 == k)
return A[right];
}
AnyType pivot = median3(A, left, right);
int i = left, j = right - 1; // from left+1 to right - 1, since we use Median of three method,
// (since later we will ++i and --j)
// we do not need to worry about the first one and the last one.
for( ; ; )
{
while( A[++i].compareTo( pivot ) < 0 && i <= right - 1)
{
}
while( A[--j].compareTo( pivot ) > 0 && j > left)
{
}
if( i < j )
swapReferences( A, i, j );
else
break;
}
swapReferences( A, i, right - 1 ); // Restore pivot
if (i + 1 > k)
return Find(A, left, i - 1, k);
if (i + 1 < k)
return Find(A, i + 1, right, k);
else
return A[i];
}
// The median-of-three method
//
private static <AnyType extends Comparable<? super AnyType>>
AnyType median3 (AnyType[] A, int left, int right)
{
int center = (left + right) / 2;
if (A[center].compareTo(A[left]) < 0 )
swapReferences(A, left, center);
if (A[right].compareTo(A[left]) < 0)
swapReferences(A, left, right);
if (A[right].compareTo(A[center]) < 0)
swapReferences(A, right, center);
swapReferences(A, center, right - 1);
return A[right - 1];
}
private static <AnyType extends Comparable<? super AnyType>>
void swapReferences(AnyType [] A, int num1, int num2)
{
AnyType temp = A[num1];
A[num1] = A[num2];
A[num2] = temp;
}
}This is the Main program which implement the routine above.
/**************************
* The Kth smallest program
*
* Author: QT_pixy
* Date: Feb. 5, 07
**************************/
import java.util.Scanner;
public class Main2
{
public static void main(String[] args)
{
Integer [] A = {23, 4, 42, 3, 13, 12};
//Integer [] A = {10, 2, 5, 23, 45, 22, 23, 4, 14, 70, 62, 3, 20, 15, 24};
// You should use larger arrays for testing your program.
Scanner input = new Scanner(System.in);
int k = input.nextInt();
while(k > 6 || k < 1)
{
System.out.println("Try again!");
k = input.nextInt();
}
Integer elem = kthsmallest.FindKthSmallest(A, k);
System.out.println(elem);
}
}


浙公网安备 33010602011771号