首页 > 编程语言 >BFPRT 算法 (TOP-K 问题)——本质就是在利用分组中位数的中位数来找到较快排更合适的pivot元素

BFPRT 算法 (TOP-K 问题)——本质就是在利用分组中位数的中位数来找到较快排更合适的pivot元素

时间:2023-08-03 21:01:14浏览次数:31  
标签:index right int TOP partition 中位数 快排 array left

BFPRT 算法 (TOP-K 问题)——本质就是在利用分组中位数的中位数来找到较快排更合适的pivot元素_算法

下面为代码实现,其所求为前 k 小的数:

#include <iostream>
#include <algorithm>

using namespace std;

int InsertSort(int array[], int left, int right);
int GetPivotIndex(int array[], int left, int right);
int Partition(int array[], int left, int right, int pivot_index);
int BFPRT(int array[], int left, int right, int k);

int main()
{
    int k = 8; // 1 <= k <= array.size
    int array[20] = { 11,9,10,1,13,8,15,0,16,2,17,5,14,3,6,18,12,7,19,4 };

    cout << "原数组:";
    for (int i = 0; i < 20; i++)
        cout << array[i] << " ";
    cout << endl;

    // 因为是以 k 为划分,所以还可以求出第 k 小值
    cout << "第 " << k << " 小值为:" << array[BFPRT(array, 0, 19, k)] << endl;

    cout << "变换后的数组:";
    for (int i = 0; i < 20; i++)
        cout << array[i] << " ";
    cout << endl;

    return 0;
}

/**
 * 对数组 array[left, right] 进行插入排序,并返回 [left, right]
 * 的中位数。
 */
int InsertSort(int array[], int left, int right)
{
    int temp;
    int j;

    for (int i = left + 1; i <= right; i++)
    {
        temp = array[i];
        j = i - 1;
        while (j >= left && array[j] > temp)
            array[j + 1] = array[j--];
        array[j + 1] = temp;
    }

    return ((right - left) >> 1) + left;
}

/**
 * 数组 array[left, right] 每五个元素作为一组,并计算每组的中位数,
 * 最后返回这些中位数的中位数下标(即主元下标)。
 *
 * @attention 末尾返回语句最后一个参数多加一个 1 的作用其实就是向上取整的意思,
 * 这样可以始终保持 k 大于 0。
 */
int GetPivotIndex(int array[], int left, int right)
{
    if (right - left < 5)
        return InsertSort(array, left, right);

    int sub_right = left - 1;

    // 每五个作为一组,求出中位数,并把这些中位数全部依次移动到数组左边
    for (int i = left; i + 4 <= right; i += 5)
    {
        int index = InsertSort(array, i, i + 4);
        swap(array[++sub_right], array[index]);
    }

    // 利用 BFPRT 得到这些中位数的中位数下标(即主元下标)
    return BFPRT(array, left, sub_right, ((sub_right - left + 1) >> 1) + 1);
}

/**
 * 利用主元下标 pivot_index 进行对数组 array[left, right] 划分,并返回
 * 划分后的分界线下标。
 */
int Partition(int array[], int left, int right, int pivot_index)
{
    swap(array[pivot_index], array[right]); // 把主元放置于末尾

    int partition_index = left; // 跟踪划分的分界线
    for (int i = left; i < right; i++)
    {
        if (array[i] < array[right])
        {
            swap(array[partition_index++], array[i]); // 比主元小的都放在左侧
        }
    }

    swap(array[partition_index], array[right]); // 最后把主元换回来

    return partition_index;
}

/**
 * 返回数组 array[left, right] 的第 k 小数的下标
 */
int BFPRT(int array[], int left, int right, int k)
{
    int pivot_index = GetPivotIndex(array, left, right); // 得到中位数的中位数下标(即主元下标)
    int partition_index = Partition(array, left, right, pivot_index); // 进行划分,返回划分边界
    int num = partition_index - left + 1;

    if (num == k)
        return partition_index;
    else if (num > k)
        return BFPRT(array, left, partition_index - 1, k);
    else
        return BFPRT(array, partition_index + 1, right, k - num);
}

运行如下:

原数组:11 9 10 1 13 8 15 0 16 2 17 5 14 3 6 18 12 7 19 4
第 8 小值为:7
变换后的数组:4 0 1 3 2 5 6 7 8 9 10 12 13 14 17 15 16 11 18 19

BFPRT 算法 (TOP-K 问题)——本质就是在利用分组中位数的中位数来找到较快排更合适的pivot元素_时间复杂度_02

BFPRT 算法 (TOP-K 问题)——本质就是在利用分组中位数的中位数来找到较快排更合适的pivot元素_中位数_03

我们选取的x可以在每次递归的时候最少淘汰(n/10-2)x3的数据量

标签:index,right,int,TOP,partition,中位数,快排,array,left
From: https://blog.51cto.com/u_11908275/6953326

相关文章

  • iTOP-STM32MP157开发板一键烧写 QT 程序到开发板
    1根据上一小节设置好编译套件后,打开自己的qt工程,然后点击qtcreator里面的项目,把编译器切换成上一章节设置好的的编译器,如下图所示:2然后打开要编译的QT代码的pro文件,在里面添加以下代码,这俩行代码的意思是说把编译的可执行程序下载到开发板的/opt目录下并执行。target.pa......
  • iTOP-RK3588开发板Ubuntu 系统交叉编译 Qt 工程-命令行交叉编译
    使用源码rk3588_linux/buildroot/output/rockchip_rk3588/host/bin/qmake交叉编译QT工程。最后烧写编译好的buildroot镜像,将编译好的QT工程可执行程序在buildroot系统上运行。交叉编译QT工程如下所示,首先进入QLed的工程目录下。然后使用以下命令交叉编译QT工程,如下......
  • Topaz Photo AI - 图片智能降噪软件mac/win版
    TopazPhotoAI是一款由TopazLabs公司开发的人工智能图像处理软件。它基于先进的机器学习技术,提供了一系列强大的功能,可以帮助用户快速、简便地改善和优化照片。点击获取TopazPhotoAI AI增强功能:TopazPhotoAI提供了多种AI增强功能,包括智能增亮、细节增强、降......
  • 迅为iTOP-RK3568开发板是怎么样的呢
    迅为iTOP-RK3568开发板是怎么样的呢CPU方面:iTOP-3568开发板采用瑞芯微RK3568处理器,内部集成了四核64位Cortex-A55处理器。主频高达2.0Ghz,RK809动态调频。集成了双核心架构GPU,ARMG522EE、支持OpenGLES1.1/2.0/32OpenCL2.0、Vulkan1.1、内嵌高性能2D加速硬件。内置独立NPU方面:算......
  • taobao.top.oaid.decrypt( OAID解密 )淘宝开放平台店铺订单解密接口,店铺订单明文接口,
    taobao.top.oaid.decrypt(OAID解密)淘宝开放平台店铺订单解密接口,店铺订单明文接口,店铺订单买家信息解密接口对接教程如下:1.公共参数名称类型必须描述(接口代码教程wx19970108018)keyString是调用key(必须以GET方式拼接在URL中,点击获取请求key和secret)secretString是调用密钥api_na......
  • 《向量数据库指南》——2023年7月国产向量数据库排行榜Top3:Milvus,Milvus Cloud,Tencent
    向量数据库排行榜分析报告随着人工智能和大数据技术的不断发展,向量数据库在各个领域的应用越来越广泛。向量数据库是一种存储和管理大规模向量数据的数据库,具有高效的数据查询和分析能力,是人工智能领域的重要基础架构。在本文中,我们将对2023年7月的国产向量数据库排行榜进行分析和......
  • iTOP-i.MX6ULL开发板Qt 串口编程
    本章内容对应视频讲解链接(在线观看):QT上位机开发之串口助手(上)→B站搜索标题→【北京迅为】嵌入式学习之QT学习篇QT上位机开发之串口助手(下)→B站搜索标题→【北京迅为】嵌入式学习之QT学习篇本节我们使用Qt来编写一个简单的上位机。实验介绍:组装ui界面,使用Qt提供的串口类......
  • 软件测试|SQL TOP提取顶部数据该如何使用?
    SQLTOP子句:提取数据库中的顶部数据简介在SQL查询语言中,TOP子句是一个非常有用的功能,它允许我们从数据库中提取指定数量的顶部数据记录。本文将深入探讨SQLTOP子句的使用方法,以及在实际应用中的一些常见场景和技巧。SQLTOPSQL是一种用于管理和操作关系型数据库的强大语言,TOP子句......
  • 使用DolphinDB TopN 函数探索高效的Alpha因子
    DolphinDB已经有非常多的窗口计算函数,例如m系列的滑动窗口计算,cum系列累计窗口计算,tm系列的的时间窗口滑动计算。但是所有这类函数都是对窗口内的所有记录进行指标计算,难免包含很多噪音。DolphinDB的金融领域用户反馈,通过交易量信息等对窗口内的记录进行过滤,得到的计算指标具......
  • iTOP-RK3568开发板Windows 安装 RKTool 驱动
    在烧写镜像之前首先需要安装RKTool驱动。RKTool驱动在网盘资料“iTOP-3568开发板\01_【iTOP-RK3568开发板】基础资料\02_iTOP-RK3568开发板烧写工具及驱动”路径下。驱动如下图所示:解压缩后,进入文件夹,如下图所示:点击“DriverInstall.exe”,如下图所示:如果出现提示,选择安装,如下......