寻找无序数组中的第K大数

本文介绍一种基于快速排序思想的算法实现,用于找出数组中第K大的元素。通过递归划分数组,该方法能在平均线性时间内完成任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用快速排序的思想,其中K从1开始
int quicksort(int * x , int l , int r , int k)
{
    if(l == r && k==1)return x[l];
    int i , j ;
    for(i=l-1 , j=l;j<r;j++)    
        if(x[j]<x[r])std::swap(x[++i] , x[j]);
    std::swap(x[++i] , x[r]);
    if(k==(i-l+1))return x[i];
    if(k<=(i-l))return quicksort(x , l , i-1 , k);
    if(k>(i-l+1)) return quicksort(x , i+1 , r , k-(i-l+1) );
}

例如寻找5, 2, 6, 3中的第3大数,排好序后变为2 , 3 , 5 , 6 , 故结果为5,可以利用上述函数cout<< quicksort(x , 0 , 3 , 3)<<endl;
注意数组从0开始,
### 关于求解第K大数的算法 #### 一、基本概念 求解第 K 大数一个经典的算法问题,通常可以通过多种方法实现。这类问题的核心在于如何高效地数组中的第 K 元素。常见的解决方式包括堆排序、快速选择以及基于二叉树的方法。 #### 二、常见解法及其优缺点 1. **堆排序 (Heap Sort)** 使用最堆或最小堆来解决问题是一种有效的方式。对于第 K 大数的问题,可以构建一个小顶堆,保持堆中始终有 K 个最的元素。当遍历到新的元素时,如果该元素于堆顶,则替换堆顶并重新调整堆结构。这种方法的时间复杂度为 \(O(n \log k)\)[^1]。 2. **快速选择 (Quick Select)** 类似于快速排序的思想,但只处理划分的一侧。通过随机选取一个枢轴(pivot),将数组划分为两部分:小于等于枢轴的部分和于枢轴的部分。根据枢轴的位置决定继续在哪一侧查目标值。平均时间复杂度为 \(O(n)\),最坏情况下为 \(O(n^2)\)[^3]。 3. **二叉搜索树 (Binary Search Tree)** 如果据流是动态变化的,还可以考虑使用平衡二叉搜索树(如红黑树)。每次插入新节点后更新其父节点的信息以便统计右子树小,从而能够迅速定位到第 K 值[^2]。 4. **计排序或其他特定场景下的优化策略** 对于某些特殊类型的输入(比如整型范围较小的情况), 可能存在更高效的解决方案, 如利用桶排序或者位运算等技术进一步降低实际运行开销[^4]。 #### 三、代码示例 - 快速选择算法 以下是采用 C++ 实现的一个简单版本的 QuickSelect 方法用于寻找未排序列表中的第 K 小/项: ```cpp #include <iostream> #include <vector> using namespace std; int partition(vector<int>& nums, int low, int high){ int pivot = nums[high]; int i = low; for(int j=low; j<high; ++j){ if(nums[j]<pivot){ swap(nums[i],nums[j]); i++; } } swap(nums[i],nums[high]); return i; } int quickselect(vector<int> &nums,int l,int r,int index){ if(l>=r)return nums[l]; int pvtIdx = rand()%(r-l+1)+l; swap(nums[pvtIdx],nums[r]); int pos = partition(nums,l,r); if(pos==index){ return nums[pos]; }else{ return pos<index?quickselect(nums,pos+1,r,index):quickselect(nums,l,pos-1,index); } } // Example usage to find the k-th largest element. double findKthLargest(vector<int>& nums, int k) { srand(time(NULL)); return quickselect(nums,0,(int)nums.size()-1,(int)(nums.size())-k); } ``` 此函 `findKthLargest` 接收参向量 `nums` 和正整 `k`, 返回给定无序集合内的第 k 高价值成员. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值