舍伍德算法

舍伍德算法主要解决算法中,避免输入所产生的时间复杂度远远超过平均时间的情况。例如快速排序或者线性时间选择中,对划分标准用概率来选取可以在很大程度上避免最坏的情况。下面是线性时间选择算法:

// 舍伍德.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include "stdafx.h"
#include"iostream"
#include<math.h>
#include<time.h>
#include<iomanip>
using namespace std;
const unsigned long maxshort=65535L;
const unsigned long multiplier=1194211693L;
const unsigned long adder=12345L;
const int INF=9999;
class RandomNumber{
private:
 //当前种子
 unsigned long randSeed;
public:
 //构造函数
 RandomNumber(unsigned long s=0);
 unsigned short Random(unsigned long n);
 double fRandom();
};


RandomNumber::RandomNumber(unsigned long s)
{
 if(s==0)
  randSeed=time(0);
 else
  randSeed=s;
}

double RandomNumber::fRandom()
{
 return Random(maxshort)/double(maxshort);
}

unsigned short RandomNumber::Random(unsigned long n)
{
 randSeed=multiplier*randSeed+adder;
 return (unsigned short)((randSeed>>16)%n);
}

//template <typename Type>
void Swap(int &a,int &b)
{
 int temp;
 temp=a;
 a=b;
 b=temp;
}

//template <typename Type>
int select(int a[],int lt,int rt,int k)
{
 //计算a[lt:rt]中第k小元素
 static RandomNumber rnd;
 while(true)
 {
  if(lt>rt)
   return a[lt];
  int i=lt,j=lt+rnd.Random(rt-lt+1);//随机选择划分基准
  Swap(a[i],a[j]);
  j=rt+1;
  int pivot=a[lt];
  while(true)
  {
   while(a[++i]<pivot);//循环找数据
   while(a[--j]>pivot);
   if(i>=j)
    break;
   Swap(a[i],a[j]);
  }
    if(j-lt+1==k)
  return pivot;
 a[lt]=a[j];
    a[j]=pivot;

 //对子数组重复划分过程
 if(j-lt+1<k)
 {
  k=k-j+lt-1;
  lt=j+1;
 }
 else
  rt=j-1;
 }
}

//template <typename Type>
int Select(int a[],int n,int k)
{
 if(k<1||k>n)
  cerr<<"Wrong!"<<endl;
 return select(a,0,n-1,k);
}

int _tmain(int argc, _TCHAR* argv[])
{
 int arr[7]={3,2,5,7,10,INF};
 cout<<Select(arr,6,5)<<endl;
 int x;
 cin>>x;
 return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值