c_cpp 【随机化算法】线性时间选择算法【7.3.1】舍伍德(舍伍德)算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 【随机化算法】线性时间选择算法【7.3.1】舍伍德(舍伍德)算法相关的知识,希望对你有一定的参考价值。
//随机化算法 线性时间选择 随机划分选择基准
#include "stdafx.h"
#include "RandomNumber.h"
#include <iostream>
using namespace std;
template<class Type>
Type select(Type a[],int l,int r,int k);
template<class Type>
Type select(Type a[],int n,int k);
template <class Type>
inline void Swap(Type &a,Type &b);
int main()
{
int a[] = {5,7,3,4,8,6,9,1,2};
cout<<"原数组为:"<<endl;
for(int i=0; i<9; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
cout<<"所给数组第7小元素为:"<<select(a,9,7)<<endl;
return 0;
}
//计算a[0:n-1]中第k小元素
//假设a[n]是一个键值无穷大的元素
template<class Type>
Type select(Type a[],int n,int k)
{
if(k<1 || k>n)
{
cout<<"请输入正确的k!"<<endl;
return 0;
}
return select(a,0,n-1,k);
}
//计算a[l:r]中第k小元素
template<class Type>
Type select(Type a[],int l,int r,int k)
{
static RandomNumber rnd;
while(true)
{
if(l>=r)
{
return a[l];
}
int i = l,
j = l + rnd.Random(r-l+1);//随机选择划分基准
Swap(a[i],a[j]);
j = r+1;
Type pivot = a[l];
//以划分基准为轴做元素交换
while(true)
{
while(a[++i]<pivot);
while(a[--j]>pivot);
if(i>=j)
{
break;
}
Swap(a[i],a[j]);
}
if(j-l+1 == k)//第k小
{
return pivot;
}
//a[j]必然小于pivot,做最后一次交换,满足左侧比pivot小,右侧比pivot大
a[l] = a[j];
a[j] = pivot;
//对子数组重复划分过程
if(j-l+1<k)
{
k = k-j+l-1;//右侧:k-(j-l+1)=k-j+l-1
l = j + 1;
}
else
{
r = j - 1;
}
}
}
template <class Type>
inline void Swap(Type &a,Type &b)
{
Type temp = a;
a = b;
b = temp;
}
//随机化算法 线性时间选择 输入预处理,洗牌
#include "stdafx.h"
#include "RandomNumber.h"
#include <iostream>
using namespace std;
template<class Type>
Type select(Type a[],int l,int r,int k);
template<class Type>
Type select(Type a[],int n,int k);
template<class Type>
void Shuffle(Type a[],int n);
template <class Type>
inline void Swap(Type &a,Type &b);
int main()
{
int a[] = {5,7,3,4,8,6,9,1,2};
cout<<"原数组为:"<<endl;
for(int i=0; i<9; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
Shuffle(a,9);//洗牌
cout<<"洗牌后数组为:"<<endl;
for(int i=0; i<9; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
cout<<"所给数组第7小元素为:"<<select(a,9,7)<<endl;
return 0;
}
//计算a[0:n-1]中第k小元素
//假设a[n]是一个键值无穷大的元素
template<class Type>
Type select(Type a[],int n,int k)
{
if(k<1 || k>n)
{
cout<<"请输入正确的k!"<<endl;
return 0;
}
return select(a,0,n-1,k);
}
//计算a[l:r]中第k小元素
template<class Type>
Type select(Type a[],int l,int r,int k)
{
while(true)
{
if(l>=r)
{
return a[l];
}
int i = l;
int j = r+1;
Type pivot = a[l];
//以划分基准为轴做元素交换
while(true)
{
while(a[++i]<pivot);
while(a[--j]>pivot);
if(i>=j)
{
break;
}
Swap(a[i],a[j]);
}
if(j-l+1 == k)//第k小
{
return pivot;
}
//a[j]必然小于pivot,做最后一次交换,满足左侧比pivot小,右侧比pivot大
a[l] = a[j];
a[j] = pivot;
//对子数组重复划分过程
if(j-l+1<k)
{
k = k-j+l-1;//右侧:k-(j-l+1)=k-j+l-1
l = j + 1;
}
else
{
r = j - 1;
}
}
}
template <class Type>
inline void Swap(Type &a,Type &b)
{
Type temp = a;
a = b;
b = temp;
}
//随机洗牌算法
template<class Type>
void Shuffle(Type a[],int n)
{
static RandomNumber rnd;
for(int i=0; i<n; i++)
{
int j = rnd.Random(n-i)+i;
Swap(a[i],a[j]);
}
}
以上是关于c_cpp 【随机化算法】线性时间选择算法【7.3.1】舍伍德(舍伍德)算法的主要内容,如果未能解决你的问题,请参考以下文章
c_cpp 【随机化算法】随机数【7.1】
c_cpp 【随机化算法】跳跃表【7.3.3】舍伍德(舍伍德)算法
c_cpp 【随机化算法】素数测试【7.5.3】蒙特卡罗(Monte Carlo)算法
c_cpp 【随机化算法】搜索有序表【7.3.2】舍伍德(舍伍德)算法
c_cpp 【随机化算法】计算定积分【7.2.2】
c_cpp 【随机化算法】计算π值【7.2.1】