Bootstrap

算法导论05--SELECT算法与随机选择算法

一、目的

1.熟悉算法设计的基本思想
2.掌握随机选择算法(rand select)的方法
3.掌握选择算法(SELECT)的方法

二、内容与设计思想

  1. 编写随机整数生成算法,生成S到T范围内的N个随机整数并输出;
  2. 编写随机选择算法和SELECT算法;
  3. 随机生成1e2、1e3、1e4、1e5、1e6个数,使用随机选择算法和SELECT算法找到第0.5N大的数输出,并画图描述不同情况下的运行时间差异;
  4. 随机生成1e6个数,使用随机选择算法和SELECT算法找到第0.2N、0.4N、0.6N、0.8N大的数输出,并画图描述不同情况下的运行时间差异;

三、使用环境

推荐使用C/C++集成编译环境。

四、实验过程

1、 写出随机选择算法的源代码

#include<bits/stdc++.h>
using namespace std;
#define MaxData 10000001
int a[MaxData]={0};

int Partition(int a[],int p,int r)
{
	int x,i,j,t;
	x=a[r];
	i=p-1;
	for (j=p;j<r;j++)
	{
		if (a[j]<=x)
		{
			i=i+1;
			t=a[i];
			a[i]=a[j];
			a[j]=t;
		 } 
	}
	t=a[i+1];
	a[i+1]=a[r];
	a[r]=t;	
	return i+1;
}

int RandomizedPartition(int a[],int p,int r)
{
	int i,t;
	i=rand()%(r-p)+p;
	t=a[i];
	a[i]=a[r];
	a[r]=t;
	
	return Partition(a,p,r);
}

int RandomizedSelect(int a[],int p,int r,int i)
{
	int q,k;
	if (r==p)
	{
		return a[p];
	}
	q=RandomizedPartition(a,p,r);
	k=q-p+1;
	if (i==k)
	{
		return a[q];
	}
	else if (i<k)
	{
		return RandomizedSelect(a,p,q-1,i);
	}
	else
	{
		return RandomizedSelect(a,q+1,r,i-k);
	}
}

int main()
{
	int i,p,r,j,X,N;
	cin>>N>>i;
	p=1;
	r=N;
	
	srand(time(0));
	for (j=1;j<=N;j++)
	{
		a[j]=rand();
		
	}
	X=RandomizedSelect(a,p,r,i);
	
	clock_t startTime,endTime;
	startTime = clock();
	X=RandomizedSelect(a,p,r,i);
    endTime = clock();
    cout << "The run time is:" <<(double)(1000*(endTime - startTime) / CLOCKS_PER_SEC) << "ms" << endl; 
	
	cout<<X;
	
	return 0;
}

2、写出SELECT算法的源代码

#include<bits/stdc++.h>
using namespace std;
#define MaxData 1000001
int a[MaxData]={0};
int MedianArr[MaxData]={0};

void InsertionSort(int a[],int p,int r)
{
	int key,i,j;
	for (j=p+1;j<=r;j++)
	{
		key=a[j];
		i=j-1;
		while (i>=p&&a[i]>key)
		{
			a[i+1]=a[i];
			i=i-1;
		}
		a[i+1]=key;
	}
}

int FindMedian(int a[],int p,int r)
{
	int i,num,remain,elem;
	if (p==r)
	{
		return a[p];
	}
	for (i=p;i<r-5;i+=5)
	{
		InsertionSort(a,i,i+4);
		num=i-p;
		MedianArr[num/5]=a[i+2];
	}
	remain=r-i+1;
	if (remain>0)
	{
		InsertionSort(a,i,r);
		num=i-p;
		MedianArr[num/5]=a[i+remain/2];
	}
	
	elem=r/5-1;
	if (r%5!=0)
	{
		elem++;
	}
	
	if (elem==0)
	{
		return MedianArr[0];
	}
	else
	{
		return FindMedian(MedianArr,0,elem);
	}
}

int Index(int a[],int p,int r,int median)
{
	for (int i=p;i<=r;i++)
	{
		if (a[i]==median)
		{
			return i;
		}
	}
}

int Partition(int a[],int p,int r)
{
	int x,i,j,t,median,index;
	median=FindMedian(a,p,r);
	index=Index(a,p,r,median);
	t=a[r];
	a[r]=a[index];
	a[index]=t;
	
	x=a[r];
	i=p-1;
	for (j=p;j<r;j++)
	{
		if (a[j]<=x)
		{
			i=i+1;
			t=a[i];
			a[i]=a[j];
			a[j]=t;
		 } 
	}
	t=a[i+1];
	a[i+1]=a[r];
	a[r]=t;
	
	return i+1;
}

int Select(int a[],int p,int r,int i)
{
	int k,q;
	if (p==r)
	{
		return a[p];
	}
	
	q=Partition(a,p,r);
	k=q-p+1;
	if (i==k)
	{
		return a[q];
	}
	else if (i<k)
	{
		return Select(a,p,q-1,i);
	}
	else
	{
		return Select(a,q+1,r,i-k);
	}
}

int main()
{
	int p,r,i,j,N,X;
	cin>>N>>i;
	p=1;
	r=N;
	
	srand(time(0));	
	for (j=1;j<=N;j++)
	{
		a[j]=rand();
	}	
	clock_t startTime,endTime;
	startTime = clock();
	X=Select(a,p,r,i);
    endTime = clock();
    cout << "The run time is:" <<(double)(1000*(endTime - startTime) / CLOCKS_PER_SEC) << "ms" << endl; 
	cout<<X;
	
	return 0;
}

3、截取各个实验的实验结果
4、分别画出各个实验结果的折线图

;