快速选择是一种选择算法,用于在无序列表中找到第k个最小的元素。它与快速排序排序算法有关。
例子:
Input: arr[] = {7, 10, 4, 3, 20, 15}
k = 3
Output: 7
Input: arr[] = {7, 10, 4, 3, 20, 15}
k = 4
Output: 10
QuickSelect算法基于QuickSort。不同之处在于,它只对包含第k个最小元素的部分重复出现,而不是对两侧都重复出现。逻辑很简单,如果分区元素的索引大于k,则针对左部分递归。如果index与k相同,则找到第k个最小元素,然后返回。如果索引小于k,则返回正确的部分。这将预期的复杂度从O(n log n)降低到O(n),最坏的情况是O(n ^ 2)。
function quickSelect(list, left, right, k)
if left = right
return list[left]
Select a pivotIndex between left and right
pivotIndex := partition(list, left, right,
pivotIndex)
if k = pivotIndex
return list[k]
else if k < pivotIndex
right := pivotIndex - 1
else
left := pivotIndex + 1
我们已经讨论了QuickSelect的递归实现。在本文中,我们将讨论简单的迭代实现。
C++
// CPP program for iterative implementation of QuickSelect
#include
using namespace std;
// Standard Lomuto partition function
int partition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (arr[j] <= pivot) {
i++;
swap(arr[i], arr[j]);
}
}
swap(arr[i + 1], arr[high]);
return (i + 1);
}
// Implementation of QuickSelect
int kthSmallest(int a[], int left, int right, int k)
{
while (left <= right) {
// Partition a[left..right] around a pivot
// and find the position of the pivot
int pivotIndex = partition(a, left, right);
// If pivot itself is the k-th smallest element
if (pivotIndex == k - 1)
return a[pivotIndex];
// If there are more than k-1 elements on
// left of pivot, then k-th smallest must be
// on left side.
else if (pivotIndex > k - 1)
right = pivotIndex - 1;
// Else k-th smallest is on right side.
else
left = pivotIndex + 1;
}
return -1;
}
// Driver program to test above methods
int main()
{
int arr[] = { 10, 4, 5, 8, 11, 6, 26 };
int n = sizeof(arr) / sizeof(arr[0]);
int k = 5;
cout << "K-th smallest element is "
<< kthSmallest(arr, 0, n - 1, k);
return 0;
}
Java
// Java program for iterative implementation
// of QuickSelect
class GFG
{
// Standard Lomuto partition function
static int partition(int arr[],
int low, int high)
{
int temp;
int pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++)
{
if (arr[j] <= pivot)
{
i++;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return (i + 1);
}
// Implementation of QuickSelect
static int kthSmallest(int a[], int left,
int right, int k)
{
while (left <= right)
{
// Partition a[left..right] around a pivot
// and find the position of the pivot
int pivotIndex = partition(a, left, right);
// If pivot itself is the k-th smallest element
if (pivotIndex == k - 1)
return a[pivotIndex];
// If there are more than k-1 elements on
// left of pivot, then k-th smallest must be
// on left side.
else if (pivotIndex > k - 1)
right = pivotIndex - 1;
// Else k-th smallest is on right side.
else
left = pivotIndex + 1;
}
return -1;
}
// Driver Code
public static void main (String[] args)
{
int arr[] = { 10, 4, 5, 8, 11, 6, 26 };
int n = arr.length;
int k = 5;
System.out.println("K-th smallest element is " +
kthSmallest(arr, 0, n - 1, k));
}
}
// This code is contributed by AnkitRai01
Python3
# Python3 program for iterative implementation
# of QuickSelect
# Standard Lomuto partition function
def partition(arr, low, high) :
pivot = arr[high]
i = (low - 1)
for j in range(low, high) :
if arr[j] <= pivot :
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return (i + 1)
# Implementation of QuickSelect
def kthSmallest(a, left, right, k) :
while left <= right :
# Partition a[left..right] around a pivot
# and find the position of the pivot
pivotIndex = partition(a, left, right)
# If pivot itself is the k-th smallest element
if pivotIndex == k - 1 :
return a[pivotIndex]
# If there are more than k-1 elements on
# left of pivot, then k-th smallest must be
# on left side.
elif pivotIndex > k - 1 :
right = pivotIndex - 1
# Else k-th smallest is on right side.
else :
left = pivotIndex + 1
return -1
# Driver Code
arr = [ 10, 4, 5, 8, 11, 6, 26 ]
n = len(arr)
k = 5
print("K-th smallest element is",
kthSmallest(arr, 0, n - 1, k))
# This code is contributed by
# divyamohan123
C#
// C# program for iterative implementation
// of QuickSelect
using System;
class GFG
{
// Standard Lomuto partition function
static int partition(int []arr,
int low, int high)
{
int temp;
int pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++)
{
if (arr[j] <= pivot)
{
i++;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return (i + 1);
}
// Implementation of QuickSelect
static int kthSmallest(int []a, int left,
int right, int k)
{
while (left <= right)
{
// Partition a[left..right] around a pivot
// and find the position of the pivot
int pivotIndex = partition(a, left, right);
// If pivot itself is the k-th smallest element
if (pivotIndex == k - 1)
return a[pivotIndex];
// If there are more than k-1 elements on
// left of pivot, then k-th smallest must be
// on left side.
else if (pivotIndex > k - 1)
right = pivotIndex - 1;
// Else k-th smallest is on right side.
else
left = pivotIndex + 1;
}
return -1;
}
// Driver Code
public static void Main (String[] args)
{
int []arr = { 10, 4, 5, 8, 11, 6, 26 };
int n = arr.Length;
int k = 5;
Console.WriteLine("K-th smallest element is " +
kthSmallest(arr, 0, n - 1, k));
}
}
// This code is contributed by 29AjayKumar
输出:
K-th smallest element is 10