基于快速排序方法改成求第k大的数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于快速排序方法改成求第k大的数相关的知识,希望对你有一定的参考价值。

基于快速排序方法改成求第k大的数
快速排序方法可以将n个无序数有序化,试基于快速排序方法编写快速求成n个无数中第k个大的数。
测试数据:自行设计,n>20, k随机输入
有没有简单的啊。给一些提示,我有点看不懂.给中文提示啊。

基于快速排序方法改成求第k大的数

int partition(const int * na, int low, int hight);
int new_qsort(const int * na, int low, int high, int nNeed);
/**
* find the k-th biggest element in a integer array, using a
* modified quick sort algorithm.
*
* Prarameters:
* narray : the start address of the integer array.
* n : the size of the integer array.
* k : the priority of the needed element.
*
* Return Value:
* -1 : array size error.
* -2 : k value invalid.
* other : the index of the k-th biggest element in the array.
*/
int find_orderk(const int * narray, const int n, const int k)

if ( n < 1)
return -1;
if ( (K < 1) || (K > n) )
return -2;
// store a copy of the original int arrray.
int * pN = new int[n];
for (int i = 0; i < n; i++)
pN[i] = narray[i];
// find the k-th biggest VALUE in the int array.

int nVal = new_qsort(pN, 0, n-1, k-1);
// find the first position of the k-th biggest VALUE in the original array.

for (int i = 0; i < n; i++)
if ( narray[i] == nVal)
return i;


/*** one pass of standard quik sort.*
* Parameters:* na : the start address of the integer array.
* low : the lower boundary of the elements needed to be processed.
* hight : the upper boundary of the elements needed to be processed.*
* Return Value:
* the index of the pivot element after this pass.
*/

int partition(const int * na, int low, int hight)

int nTmp = na[low];
while (low < high )

while(low < high && na[high] <= nTmp)
high--;
na[low] = na[high];
while (low < high && na[low] >= nTmp)
low++;
na[higt] = na[low];
na[low] = nTmp;
return low;

/*** modified qsort, only sort the part that contains the
* nNeed-th biggest element. The return value is the value of
* the nNeed-th biggest element, not the position.*
* Parameters:
* na : the start address of the integer array.
* low : the lower boundary of the elements needed to be processed.
* hight : the upper boundary of the elements needed to be processed.
* nNeed : the priority of the needed element.*
* Return Value:
* the value of the nNeed-th biggest element in the given integer array.
*/

int new_qsort(const int * na, int low, int high, int nNeed)

int nFound = partition(na, low, high);
if (nFound == nNeed)

return na[nFound];

if (nFound < nNeed)

return new_qsort(na, nFound, high);

if (nFound > nNeed)

return new_qsort(na, low, nFound);

参考资料:测试数据:自行设计,n、k、数组随机输入

参考技术A 用链表吧,很方便的,很简洁的

求第k大的数(用到快速排序算法的思想)

//下面两种part效率比较:相同运算量下part比part2快5倍左右,part2写法简单但是效率低

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;

int part(int *arr, int l , int r)
{
    c_num += r - l;
    swap(arr[r],arr[l+rand()%(r-l)]);
    int q = r--;
    while( l < r)
    {
        while(l <= r && arr[l] <= arr[q]) ++l; 
        while(l < r && arr[r] >= arr[q]) --r;
        if(l<r&&arr[l]>arr[r]) swap(arr[l], arr[r]);
    }
    if(l<q&&arr[l]>arr[q]) swap(arr[l], arr[q]);    
    return l;
}

int part2(int *arr, int l , int r)
{
    c_num += r - l;
    int k, q = l;
    swap(arr[l], arr[l+rand()%(r-l)]);
    for(k = l+1; k <= r; ++k) 
    {
        if(arr[k] <= arr[q])
        {
            if(++l != k)
                swap(arr[l], arr[k]);
        }
    }
    swap(arr[l], arr[q]);    
    return l;
}

void qsort(int *arr, int l, int r)
{
    if(l >= r) return;
    int mid = part(arr, l , r);
    qsort(arr, l, mid-1);
    qsort(arr,mid+1, r);
}

int findNumK(int *arr, int l, int r, const int k)
{
    if(l >= r)
    {
        return arr[k];
    }
    int mid = part(arr, l , r);
    if(k < mid)
    {
        return findNumK(arr, l, mid-1, k);
    }
    else if (k > mid)
    {
        return findNumK(arr,mid+1, r, k);
    }
    else
    {
        return arr[k];
    }
}
#define MAX_RAND 82934829
int myRand(int n)
{
    return  (long((double)rand()/RAND_MAX * MAX_RAND))%n;
}
const int n = 10000000;
int ki = 100;
int arr[n];
int brr[n];
int _tmain(int argc, _TCHAR* argv[])
{
    for(int i = 0; i < n; ++i)
    {
        arr[i] = i;
    }
    for(int i = 0; i < n; ++i)
    {
        swap(arr[i],arr[myRand(n)]);
    }
    for(int i = 0; i < n; ++i)
    {
        brr[i] = arr[i];
    }
    printf("@@@@@@@\n");
    while(cin>>ki)
    {
        printf("\n%d %d\n", c_num, findNumK(brr, 0, n-1, n-ki));
        for(int i = 0; i < n; ++i)
        {
            brr[i] = arr[i];
        }
        c_num = 0;
    }
    printf("\n################\n");    
    c_num = 0;
    qsort(arr, 0, n-1);
    for(int i = n-1; i >= n - ki; --i)
    {        
        printf("%d ", arr[i]);
    }
    printf("\n%d\n",c_num);
    getchar();
    return 0;
}

 

以上是关于基于快速排序方法改成求第k大的数的主要内容,如果未能解决你的问题,请参考以下文章

2020-03-02:在无序数组中,如何求第K小的数?

如何查找无序数组中的Top n

P1923 求第 k 小的数

P1923 求第 k 小的数

P1923 求第 k 小的数

P1923 求第 k 小的数