记录_选择算法_BFPRT

 //数组大小确定 找第k大 一个位置确定(分治(快排))的值的的下标正好等于k 这个数为第k大
//因为数组大小确定 类似二分 当一个划分后的数的下标正好等于 k 时 此数为要查找数
//而因为为划分后的数 所以可以明显知道 求的 k 个数是在左边还是右边

void nswap(int &a, int &b) {
    int t = a;
    a = b;
    b = t;
}


void bubble(int *arr, int l, int r) {
    for (int i = l; i < r + 1; ++i)
        for (int j = l; j < r - i; ++j)
            if (*(arr + j) < *(arr + j + 1))
                neSwap(*(arr + j), *(arr + j + 1));
}

int parttion(int *arr, int l, int r, int loc) {
    int i = l - 1;
    nswap(*(arr + loc), *(arr + r));//交换到右边 进行划分
    for (int j = l; j < r; ++j)
        if (*(arr + j) < *(arr + r))
            nswap(*(arr + (++i)), *(arr + j));
    nswap(*(arr + (++i)), *(arr + r));//将r移到准确位置
    return i;
}

//找出中位数 的中位数 对数组进行划分 找出第 k 大所在的左右位置 递归找出第k大数

int select(int *arr, int l, int r, int n, int k) {//k代表第几大 n代表元素个数
    int i = 0;//片段内游标
    int size = r - l + 1;//片段大小
    //排序得到中位数
    for (; i < size / 5; ++i) {//片段内元素个数为 r-l+1 个
        bubble(arr, 5 * i + l, 5 * i + l + 4);//排序
        nswap(arr[l + i], arr[l + 5 * i + 2]);//将中位数添加到前面方便查找中位数
    }
    //不足5个 排序得到中位数
    bubble(arr, i * 5 + l, r);//跳到没有5个的位置
    nswap(arr[l + i], arr[(l + r + 1 + i * 5) / 2]);//交换中位数较小的哪一位arr + l + i * 5 + (size - i * 5) / 2)
    //找出中位数的中位数
    bubble(arr, l, l + i);
    //按位置划分 并得到准确位置
    int loc = parttion(arr, 0, n - 1, l + i / 2);
    if (loc == k) return arr[loc];
    else if (loc > k) return select(arr, l, loc - 1, n, k);
    else if (loc < k)return select(arr, loc + 1, r, n, k);
}

int BFPRT(int *arr, int n, int k) {
    if (k > 0 && k <= n) {
        return select(arr, 0, n - 1, n, k - 1);
    }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值