/*
线性时间选择算法:
含义:是解决选择问题的分治算法
与快速排序不同的是:快排递归处理划分的两边,而线性选择只对其中
的一个部分进行处理
时间复杂度:O(n)
实现:需要用到随机划分函数
主要的过程好似:A[p...r]通过随机划分函数得到枢轴q
根据划分的两个区间A[p...q-1],A[q],A[q+1...r]
然后判断<=A[q]的元素数量k=q-p+1 与 需要寻找的第i小的关系
如果 k == i,直接返回A[q]
如果 k > i,说明第i小的元素只可能在区间A[p...q-1]中
如果 k < i ,说明第i小的元素在区间A[q+1...r]中 ,并且问题转化为在A[q+1...r]中寻找第i-k小的元素
输入的第一行的第一个数n表示数组元素个数,第二个数i表示该数组中第i小的数
输入:
7 3
329 457 657 839 436 720 355
输出:
436
*/
#include <iostream>
#include <stdlib.h>
#include <stdlib.h>
using namespace std;
//返回iMin~iMax中的任意数字
int myrandom(int iMin,int iMax)
{
// 3~6,6-3=3 ,
int iResult = rand() % (iMax - iMin + 1) + iMin;
return iResult;
}
void swap(int* pArr , int p , int q)
{
int iTemp = pArr[p];
pArr[p] = pArr[q];
pArr[q] = iTemp;
}
int randomPartition(int* pArr,int iLow ,int iHigh)
{
int iRand = myrandom(iLow , iHigh);
swap(pArr , iRand , iLow);
int iPivot = pArr[iLow];
//下面就是快排的枢轴划分
while(iLow < iHigh)
{
while(iLow < iHigh && pArr[iHigh] >= iPivot)
{
iHigh--;
}
pArr[iLow] = pArr[iHigh];
while(iLow < iHigh && pArr[iLow] <= iPivot)
{
iLow++;
}
pArr[iHigh] = pArr[iLow];
}
pArr[iLow] = iPivot;
return iLow;
}
int randomizedSelect(int* pArr,int p ,int r,int i)
{
if(p == r)
{
return pArr[p];
}
int q = randomPartition(pArr, p ,r);
int k = q - p + 1;
if(i == k)
{
return pArr[q];
}
//在低区间
else if(i < k)
{
int iResult = randomizedSelect(pArr, p , q-1 ,i);
return iResult;
}
else
{
int iResult = randomizedSelect(pArr , q + 1 , r , i - k);
return iResult;
}
}
void process()
{
int n,u;
while(cin >> n >> u)
{
int* pArr = new int[n];
for(int i = 0; i < n ; i++)
{
cin >> pArr[i];
}
int iResult = randomizedSelect(pArr, 0 , n -1 , u);
cout << iResult << endl;
delete[] pArr;
}
}
int main(int argc,char* argv[])
{
process();
getchar();
return 0;
}
算法导论:第9章 中位数和顺序统计量_1期望为线性时间的选择算法
最新推荐文章于 2024-06-23 11:07:45 发布