python 实现quick select快速选择算法

quick select快速选择算法介绍

快速选择算法(QuickSelect)是一种在未排序的数组中查找第k小/大元素的算法,其基本思想类似于快速排序算法,但不同的是快速选择算法只需要对数组的一部分进行排序,而不需要对整个数组进行排序。以下是对快速选择算法的详细解释:

基本思想

快速选择算法的基本思想是选择一个基准值(pivot),将数组分为两部分,一部分小于等于基准值,另一部分大于基准值。然后根据k与基准值的大小关系,选择其中一部分进行递归搜索,直到找到第k小/大元素为止。

时间复杂度
平均时间复杂度:O(n),其中n是数组的大小。
最坏时间复杂度:O(n^2),但这种情况出现的概率很低。
空间复杂度

快速选择算法的空间复杂度为O(1),因为它只需要少量的额外空间来存储递归调用栈、基准值和一些临时变量。

基本步骤
选择一个基准值pivot:可以选择数组中的任意一个元素,但通常选择第一个、最后一个或中间元素作为基准值。
将数组分为两部分:通过一趟排序(实际上是分区操作),将数组分为小于等于基准值的左子数组和大于基准值的右子数组。
递归搜索:
如果k小于等于左子数组的长度,那么第k小元素在左子数组中,继续对左子数组进行递归搜索。
如果k等于左子数组长度加一,那么基准值就是第k小元素,算法结束。
如果k大于左子数组的长度,那么第k小元素在右子数组中,继续在右子数组中查找,此时k需要更新为k减去左子数组长度再减一。
重复步骤2和3,直到找到第k小元素为止。
示例代码

以下是一个简单的快速选择算法的实现示例(用于查找第k小的元素):

void quickSelect(int arr[], int left, int right, int k) {
    if (left == right) {  // 如果区间内只有一个数,则该数即为第k小的数
        if (k == 1) cout << arr[left];
        return;
    }

    int i = left, j = right, pivot = arr[(left + right) / 2];

    // 分区操作
    while (i <= j) {
        while (arr[j] > pivot) j--;
        while (arr[i] < pivot) i++;
        if (i <= j) {
            swap(arr[i], arr[j]);
            i++;
            j--;
        }
    }

    // 判断第k小元素在左子数组还是右子数组,并递归查找
    if (k <= j)
        quickSelect(arr, left, j, k);
    else if (k <= right)
        quickSelect(arr, i, right, k - j - 1);
}

注意事项
快速选择算法在处理大数据集时非常高效,但在最坏情况下性能可能下降。
在实际应用中,可以通过随机选择基准值或使用其他优化策略来提高算法的性能和稳定性。

希望以上信息能帮到你。如果你有更具体的问题或需要进一步的解释,请随时告诉我。

quick select快速选择算法 python实现样例

快速选择算法是一种在未排序的数组中查找第k小元素的算法。它是基于快速排序算法的思想,通过选择一个基准元素,将数组分为两个部分,并且只对需要的部分进行递归处理,从而减少了比较和交换的次数。

下面是用Python实现快速选择算法的代码:

def partition(nums, low, high):
    pivot = nums[high]
    i = low - 1
    for j in range(low, high):
        if nums[j] <= pivot:
            i += 1
            nums[i], nums[j] = nums[j], nums[i]
    nums[i+1], nums[high] = nums[high], nums[i+1]
    return i+1
    
def quick_select(nums, low, high, k):
    if low == high:
        return nums[low]
    pivot_index = partition(nums, low, high)
    if k == pivot_index:
        return nums[k]
    elif k < pivot_index:
        return quick_select(nums, low, pivot_index-1, k)
    else:
        return quick_select(nums, pivot_index+1, high, k)

def quick_select_wrapper(nums, k):
    return quick_select(nums, 0, len(nums)-1, k-1)

nums = [3, 1, 5, 2, 4]
k = 3
result = quick_select_wrapper(nums, k)
print(f"The {k}th smallest element is: {result}")

该代码中,partition函数用于选择一个基准元素,并将数组分为两个部分,小于基准元素的放在其左边,大于基准元素的放在右边。quick_select函数根据基准元素的位置进行递归处理,最终找到第k小元素。quick_select_wrapper函数则用于对外提供接口,将k转换为索引形式,方便调用快速选择函数。

上述代码输出结果为:

The 3th smallest element is: 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luthane

您的鼓励将是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值