随机算法实验—舍伍德法求解线性时间元素选择问题

实验名称
随机算法实验—舍伍德法求解线性时间元素选择问题。

实验目的
随机算法实验—舍伍德法求解线性时间元素选择问题。

实验原理
使用舍伍德型选择算法,根据不同的输入用例,能准确的输出用例中的中值, 并计算出程序运行所需要的时间。

实验步骤
① 判断是否需要进行随机划分;
② 产生随机数 j,选择划分基准,将 a[j]与 a[l]交换;
③ 以划分基准为轴做元素交换,使得一侧数组小于基准值,另一侧数组值大于基准值;
④ 判断基准值是否就是所需选择的数,若是,则输出;若不是对子数组重复步骤②③。

时间复杂度分析
设T(n)是算法select作用于一个含有n个元素的输入数组上所需的期望时间的上界,且T(n)单增。在最坏的情况下,第k小元素总是被划分在较大的子数组中。由此可以得到递归式:
在这里插入图片描述

解上面的递归式可得T(n)=O(n)。

实验心得
通过这次实验,我回顾了线性时间选择问题的基本解题思路。

#include <iostream>
#include <iomanip>
#include <time.h>
#include<algorithm>
#include <windows.h>
#include<fstream>
using namespace std;
ifstream ifile("input.txt");
ofstream ofile("output.txt");
const int INF = 9999;
int arr[10000];
int k;
const unsigned long maxshort = 65535L;
const unsigned long multiplier = 1194211693L;
const unsigned long adder = 12345L;
class RandomNumber{
private:
    unsigned long randSeed;
public:
    RandomNumber(unsigned long s = 0);
    unsigned short Random(unsigned long n);
};
RandomNumber::RandomNumber(unsigned long s)
{
    if(s == 0)
        randSeed = time(0);    
    else
        randSeed = s;
}
unsigned short RandomNumber::Random(unsigned long n)
{
    randSeed = multiplier * randSeed + adder;
    return (unsigned short)((randSeed >> 16) % n);
}

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

int select(int a[], int lt, int rt, int 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;
    }
}
 
int Select(int a[], int n, int k)
{
    if(k < 1 || k > n)cerr << "Wrong!" << endl;
    return select(a, 0, n-1, k);
}
 
void init(int n)
{
	for(int i=0;i<n;i++)
		ifile>>arr[i]; 
	static RandomNumber rnd;
	k = rnd.Random(n-1)+1;
} 

int main()
{
    LARGE_INTEGER frequency;
 	double v,beginoftime,endoftime,dt,t; 
    init(7);
    sort(arr,arr+7);
	for(int i=0;i<7;i++) ofile<<arr[i]<<" "; 
	ofile << endl << Select(arr,7, 4) << endl; 
 
 	ifile.close();
	ifile.open("10.txt"); 
	cout<<"10 SISE:\n";
	init(10);
 	QueryPerformanceFrequency(&frequency);
 	v=(double)frequency.QuadPart;
 	QueryPerformanceCounter(&frequency);
    beginoftime=frequency.QuadPart;
    cout << Select(arr,10, k);   
 	QueryPerformanceCounter(&frequency);
    endoftime=frequency.QuadPart;
    dt=(double)(endoftime-beginoftime);
    t=dt/v;
	cout<<endl<<"Time is "<<t*1000<<"ms\n";
	
	ifile.close();
	ifile.open("100.txt"); 
	cout<<"100 SISE:\n";
	init(100);
 	QueryPerformanceFrequency(&frequency);//获得时钟频率
 	v=(double)frequency.QuadPart;//取得频率*/
 	QueryPerformanceCounter(&frequency);
    beginoftime=frequency.QuadPart;//获得初始值
	cout << Select(arr,100,k);
 	QueryPerformanceCounter(&frequency);
    endoftime=frequency.QuadPart;//获得终止值
    dt=(double)(endoftime-beginoftime);//差值 
    t=dt/v;//差值除以频率得到时间
	cout<<endl<<"Time is "<<t*1000<<"ms\n";	
	
	ifile.close();
	ifile.open("10000.txt"); 
	cout<<"10000 SISE:\n";
	init(10000);
 	QueryPerformanceFrequency(&frequency);//获得时钟频率
 	v=(double)frequency.QuadPart;//取得频率*/
 	QueryPerformanceCounter(&frequency);
    beginoftime=frequency.QuadPart;//获得初始值
	cout << Select(arr,10000, k);
 	QueryPerformanceCounter(&frequency);
    endoftime=frequency.QuadPart;//获得终止值
    dt=(double)(endoftime-beginoftime);//差值
    t=dt/v;//差值除以频率得到时间
	cout<<endl<<"Time is "<<t*1000<<"ms\n";
    
}
#include <iostream>
#include <time.h>
#include <fstream>
using namespace std;
const int maxn=10000;
int A[maxn]={0};
int Size[5]={10,100,10000};
void print(ofstream &outfile,int n)
{
	for(int i=0;i<n;i++)
	{
		outfile<<A[i]<<' ';
	}
}
int main()
{
    int n=0;
    //ifstream
    ofstream out_10("10.txt"),out_100("100.txt"),out_10000("10000.txt");
    srand(time(NULL));
    for(int i=0;i<Size[0];i++) A[i]=rand()%maxn;
    print(out_10,Size[0]);
    for(int i=0;i<Size[1];i++) A[i]=rand()%maxn;
    print(out_100,Size[1]);
    for(int i=0;i<Size[2];i++) A[i]=rand()%maxn;
    print(out_10000,Size[2]);
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值