C++ 快排思想 求第k大的数据(3种方法)、第k小的数据(3种方法)

本文介绍使用C++实现快速排序算法来查找数组中第k大的元素和第k小的元素的多种方法。包括两种不同版本的快速排序实现,并通过具体示例展示了如何应用这些算法。
部署运行你感兴趣的模型镜像

C++ 快排思想 求第k大的数据(3种方法)、第k小的数据(3种方法)

#include<iostream>
using namespace std;

//找出数组中第k大的数 法1 二路快排1
int quicksort_k_big1(int a[], int l, int r, int k)//从大到小排序
{
    if (l >= r) return a[l];
    int v = a[l];//基准

    //i,j左右分块的初始值, 要保证初始化时,俩个子数组都为空,即,数组右端索引<左端索引
    int i = l + 1;//a[l+1...i-1]>v
    int j = r;//a[j+1...r]<v

    while (true){
        while (i <= r && a[i] > v) ++i;//降序
        while (j >= l + 1 && a[j] < v) --j;
        if (i > j) break;
        swap(a[i], a[j]);
        ++i;
        --j;
    }
    swap(a[l], a[j]);

    if (j == k) return a[j];
    if (j < k) return quicksort_k_big1(a, j + 1, r, k);
    else return quicksort_k_big1(a, l, j - 1, k);
}

//找出数组中第k小的数 法1_1 二路快排1
int quicksort_k_small1_1(int a[], int l, int r, int k)//从大到小排序
{
    if (l >= r) return a[l];
    int v = a[l];//基准

    //i,j左右分块的初始值, 要保证初始化时,俩个子数组都为空,即,数组右端索引<左端索引
    int i = l + 1;//a[l+1...i-1]>v
    int j = r;//a[j+1...r]<v

    while (true){
        while (i <= r && a[i] > v) ++i;//降序
        while (j >= l + 1 && a[j] < v) --j;
        if (i > j) break;//循环结束标志
        swap(a[i], a[j]);
        ++i;
        --j;
    }
    swap(a[l], a[j]);

    int th = r - k;//设定好 降序时 第k小的数 对应 的是 正序时的 第th大的数

    if (j == th) return a[j];
    if (j < th) return quicksort_k_small1_1(a, j + 1, r, k);
    else return quicksort_k_small1_1(a, l, j - 1, k);
}

//找出数组中第k小的数 法1 二路快排1
int quicksort_k_small1(int a[], int l, int r, int k)//从小到大排序
{
    if (l >= r) return a[l];
    int v = a[l];//基准

    //i,j左右分块的初始值 左:a[l+1...i-1]>v 右:a[j+1...r]<v
    int i = l + 1, j = r;

    while (true){
        while (i <= r  && a[i] < v) ++i;
        while (j >= l + 1 && a[j] > v) --j;

        if (i > j) break;//退出while循环

        swap(a[i], a[j]);
        ++i;
        --j;
    }
    swap(a[l], a[j]);

    if (j == k) return a[j];
    if (j < k) return quicksort_k_small1(a, j + 1, r, k);
    else return quicksort_k_small1(a, l, j - 1, k);
}

//找出数组中第k大的数 法1_1 二路快排1
int quicksort_k_big1_1(int a[], int l, int r, int k)//从小到大排序
{
    if (l >= r) return a[l];
    int v = a[l];//基准

    //i,j左右分块的初始值 左:a[l+1...i-1]>v 右:a[j+1...r]<v
    int i = l + 1, j = r;

    while (true){
        while (i <= r  && a[i] < v) ++i;//升序
        while (j >= l + 1 && a[j] > v) --j;

        if (i > j) break;//退出while循环

        swap(a[i], a[j]);
        ++i;
        --j;
    }
    swap(a[l], a[j]);

    int th = r - k;//设定好 升序时 第k大的数 对应 的是 正序时的 第th小的数

    if (j == th) return a[j];//因为基准元素的索引j是正序的,所以,与转换成正序的第th小的数相比较,会更好一些。
    if (j < th) return quicksort_k_big1_1(a, j + 1, r, k);
    else return quicksort_k_big1_1(a, l, j - 1, k);
}

//找出数组中第k大的数 法2 二路快排2
int quicksort_k_big2(int a[], int l, int r, int k)
{
    if (l >= r) return a[l];
    int v = a[l];

    //i,j左右分块的初始值 左:a[l...i-1]>=v 右:a[j...r]<=v
    int i = l, j = r;
    while (i < j)
    {
        while (i < j && a[j] <= v) --j;
        if (i < j) a[i++] = a[j];
        while (i < j && a[i] >= v) ++i;
        if (i < j) a[j--] = a[i];
    }
    a[i] = v;
    if (i == k) return a[i];
    if (i < k) return quicksort_k_big2(a, i + 1, r, k);
    else return quicksort_k_big2(a, l, i - 1, k);
}

//找出数组中第k小的数 法2 二路快排2
int quicksort_k_small2(int a[], int l, int r, int k)//从小到大排序
{
    if (l >= r) return a[l];
    int v = a[l];

    //i,j左右分块的初始值 左:a[l...i-1]<=v 右:a[j...r]>=v
    int i = l, j = r;

    while (i < j)
    {
        while (i < j && a[j] >= v) --j;
        if (i < j) a[i++] = a[j];
        while (i < j && a[i] <= v) ++i;
        if (i < j) a[j--] = a[i];
    }
    a[i] = v;

    if (i == k) return a[i];
    if (i < k) return quicksort_k_small2(a, i + 1, r, k);
    else return quicksort_k_small2(a, l, i - 1, k);
}

int main()
{
    int a[] = { 100, 8, 4, 6, 5, 98, 0, 7, 100, 4, 8, 0, 8, 2, 1, 9, 3, 6 };
    int n = sizeof(a) / sizeof(a[0]);

    //测试 二路快排 法1 找出数组中第k大的数 
    cout << "---quicksort_k_big1--------" << endl;
    for (int k = 1; k <= n; ++k)//测试从第1-n的所有数据
        cout << quicksort_k_big1(a, 0, n - 1, k - 1) << "\t";
    cout << endl;

    //测试 二路快排 法3 找出数组中第k大的数 
    cout << "---quicksort_k_big1_1--------" << endl;
    for (int k = 1; k <= n; ++k)//测试从第1-n的所有数据
        cout << quicksort_k_big1_1(a, 0, n - 1, k - 1) << "\t";
    cout << endl;

    //测试 二路快排 法2 找出数组中第k大的数 
    cout << "---quicksort_k_big2--------" << endl;
    for (int k = 1; k <= n; ++k)//测试从第1-n的所有数据
        cout << quicksort_k_big2(a, 0, n - 1, k - 1) << "\t";
    cout << endl;

    //测试 找出数组中第k小的数 法1
    cout << "---quicksort_k_small1--------" << endl;
    for (int k = 1; k <= n; ++k)//测试从第1-n的所有数据
        cout << quicksort_k_small1(a, 0, n - 1, k - 1) << "\t";
    cout << endl;

    //测试 找出数组中第k小的数 法1_1
    cout << "---quicksort_k_small1_1--------" << endl;
    for (int k = 1; k <= n; ++k)//测试从第1-n的所有数据
        cout << quicksort_k_small1_1(a, 0, n - 1, k - 1) << "\t";
    cout << endl;

    //测试 找出数组中第k小的数 法2
    cout << "----quicksort_k_small2-------------------------" << endl;
    for (int k = 1; k <= n; ++k)//测试从第1-n的所有数据
        cout << quicksort_k_small2(a, 0, n - 1, k - 1) << "\t";
    cout << endl;

    return 0;
}

这里写图片描述

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值