求一列数的第k大的数

本文介绍了一种类似于快速排序的算法——快速选择算法,它可以在O(n)时间复杂度下找到数组中的第k小元素,算法通过递归调用Partition函数实现排序并查找目标值。

C/C++实现
类似于快排,也可以说是快排的延伸
比求最大或者最小数的那种算法灵活多了,显然很通用的。

#include<stdio.h>

int partition(int a[],int low,int high)
{
    int pivotkey=a[low];
    while(low<high)
    {
        while(low<high&&a[high]>=pivotkey)
            high--;
        a[low]=a[high];

        while(low<high&&a[high]<=pivotkey)
            low++;
        a[high]=a[low];
    }
    a[low]=pivotkey;
    return low;
}//Partition

int select(int a[],int low,int high,int k)//求第k小的数 
{
    if(low==high)  
        return a[low];  
    int loc=partition(a,low,high);//返回一趟快排后某个基准点的位置  
    int kth=loc-low+1;//该基准数在当前的子数组中是第几小的数  
    if(k==kth)//如果该趟排序后返回的基准位置所处的位置正好是这个子数组的第k小的数  
        return a[loc];//返回处于该位置的值就是要求的第k小的数  
    else if(k<kth)  
        return select(a,low,loc-1,k);//求左边子数组中的第k小的数  
    else 
        return select(a,loc+1,high,k-kth);//求右边子数组中的第k-kth小的数    
}  

void main()
{
    int low=0, high=9, a[]={1,2,3,4,5,6,7,8,9,10},k;
    k=select(a,0,9,5);
    printf("%d",k);
}
<think>我们参考引用[1]中提到的排序方法:使用外部命令sort对文本进行排序。具体来说,用户想按照第三列字进行排序(注意第三列包含字和单位,如"3 KB")。 引用[1]中给出了一个例子:按照第二列字排序(使用-k2n),以及一个结合第三列和第四列排序的例子(使用-k4 -bk3g)。但用户的需是按第三列字排序,而第三列是字加单位(如"1476"是纯字,但后面有单位"KB"等)。实际上,第三列是纯字(没有小点,也没有空格),但后面紧接着是第四列的单位。因此,我们可以将第三列和第四列视为两个不同的列(以空格分隔)。 观察引用[1]的例子文本: cwljfklla 1476 3 KB faldfjala 1129 968 KB ... 这里每行有四个字段(列),以空格分隔。第三列是字(字符串形式),第四列是单位。 但是用户要按照第三列的字排序(即小),那么我们可以使用sort命令的-k选项指定第三列,并按照值排序(使用'n'选项,表示值比较)。 具体命令为: :%!sort -k3n 解释: % 表示整个文件 ! 表示使用外部命令 sort 是排序命令 -k3n 表示按第三列进行值排序(n表示numeric) 然而,注意例子中第三列的字后面紧跟着第四列的单位,而单位字符串(如"KB")可能会影响排序(因为如果按字符串排序,就会出现"1KB"和"2KB"这样的字符串比较,而值排序则不需要考虑单位,因为单位在第四列)。所以,我们只需要按第三列值排序即可。 但是,如果第三列和第四列之间没有用空格分隔(即第三列的字和单位连在一起),那么我们就需要先进行分割。但根据引用[1]的例子,它们是用空格分隔的,所以直接按第三列排序即可。 另外,引用[1]中还有一个例子是按照文件小排序,它使用了: :%!sort -k4 -bk3g 这个命令比较复杂,其中: -k4 表示按第四列排序(但这里第四列是单位,如KB、MB等) -b 表示忽略前导空白 -k3g 表示按第三列使用一般值排序(g支持科学计法、浮点等,但这里第三列是整,所以用n也可以) 但实际上,用户的需是“按第三列字排序”,所以我们不需要考虑单位(因为单位在第四列)。因此,简单的按第三列值排序即可。 但是,如果用户的据中第三列和第四列之间没有空格分隔(即第三列是字和单位连在一起的,例如"3KB"),那么我们就需要先将单位去掉,然后再排序。但根据引用[1]提供的例子,第三列和第四列是分开的,所以我们采用简单方法。 因此,回答如下: 在gvim中,您可以使用外部sort命令对文件内容按照第三列字进行排序。具体步骤是: 1. 打开要排序的文件。 2. 在命令模式下输入:`:%!sort -k3n` - `%` 表示整个文件 - `!` 表示使用外部命令 - `sort -k3n` 表示按照第三列(值排序) 注意:这个命令假设您的文件中的列是以空格分隔的,并且第三列是纯字(没有单位,单位在第四列)。排序后,文件内容将按照第三列的字从小到排序。 如果您希望从到小排序,可以加上`-r`选项(反向排序): `:%!sort -k3n -r` 如果您的据中第三列包含单位(与字在同一列),那么您需要先进行预处理(例如,将字和单位分离),然后再排序。但根据引用[1]的示例,第三列和第四列是分开的,所以直接使用上述命令即可。 另外,如果列之间不是用空格分隔(比如用制表符),那么sort命令默认会以空白(空格或制表符)作为分隔符,所以通常也可以正确识别。如果分隔符是其他字符,可以使用`-t`选项指定,例如`-t','`表示以逗号分隔。 如果您的据格式与引用[1]中的示例不同,请提供具体的据格式以便进一步调整命令。 根据引用[2]和[3],它们主要介绍了gvim的列操作和基本配置,与排序关系不,因此我们主要参考引用[1]的方法。 因此,推荐的方法是:`: %!sort -k3n` 示例: 排序前: a 100 10 KB b 200 5 KB c 300 20 KB 排序后(按第三列值从小到): b 200 5 KB a 100 10 KB c 300 20 KB 注意:如果第三列有负或小,使用`-k3n`也能正确排序(因为n选项支持整,如果是小则应该用g选项,但这里根据据情况,如果据是小,则使用`-k3g`)。但引用[1]的例子中第三列是整,所以用n即可。如果您的据包含小,请使用`-k3g`。 因此,如果第三列是浮点,建议使用: `:%!sort -k3g` 总结:根据第三列的据类型选择n(整)或g(浮点)。 §§相关问题§§ 1. 在gvim中如何按照多列排序(例如先按第三列,再按第四列)? 2. 如果列之间的分隔符不是空格,如何指定分隔符进行排序? 3. 如何将排序后的结果保存到另一个文件而不影响原文件? </think> 在gvim中按照第三列字进行排序,可以通过外部`sort`命令结合列选择参实现。具体步骤如下: ### 排序方法 1. **基础命令**(适用于第三列为纯字): ```vim :%!sort -k3n ``` - `%`:对整个文件操作 - `!`:调用外部命令 - `-k3n`:按第三列(`3`)值排序(`n`表示值类型) 2. **复杂情况**(如第三列含单位 "KB/MB"): ```vim :%!sort -k3.1,3.2g ``` - `-k3.1,3.2g`:从第三列第1字符到第2字符截取字部分,按通用值排序(`g`支持浮点/科学计法)[^1]。 --- ### 操作步骤 1. 在gvim中打开文件。 2. 进入命令模式(按`Esc`)。 3. 输入上述任一命令: - 若第三列为纯字(如 `1476`),用 `:%!sort -k3n`。 - 若第三列含单位(如 `3 KB`),用 `:%!sort -k3.1,3.2g`。 4. 按回车执行,文件将按第三列值重新排序。 --- ### 示例说明 **原始据**: ``` cwljfklla 1476 3 KB faldfjala 1129 968 KB dadfadfas 272 31 KB ``` **执行 `:%!sort -k3n` 后**(按第三列字升序): ``` cwljfklla 1476 3 KB → 最小值(3) dadfadfas 272 31 KB faldfjala 1129 968 KB → 最值(968) ``` --- ### 注意事项 - **列分隔符**:默认以空格分列。若使用其他分隔符(如逗号),需加 `-t`,` 参,如: ```vim :%!sort -t',' -k3n # 以逗号作为列分隔符 ``` - **反向排序**:添加 `-r` 参(如 `:%!sort -k3n -r` 从到小排序)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值