实验一  算法练习

实验一  算法练习

l        实验所属系列:离散数学课后实验

l        实验对象:本科

l        相关课程及专业:离散数学,计算机专业

l        实验类型: 课后实验

l        实验时数(学分): 3学时

实验目的

  1. 熟悉算法的编写;
  2. 分析算法的时间复杂度。

实验内容与要求

1、题目(杭电OJ——acm.hdu.edu.cn上hdu 1425 sort

Time Limit: 6000/1000MS (Java/Others)  Memory Limit: 64M/32M (Java/Others)

给n个整数,按从大到小的顺序输出其中前m大的数。

输入:每组测试数据有两行,第一行有两个数n, m(0 < n, m < 1000000),第二行包含n个各不相同,且都处于区间[-500000, 500000]的整数。

输出:对每组测试数据按从大到小的顺序输出前m大的数。

Sample Input

5 3

3 -35 92 213 -644

Sample Output

213 92 3

2、实验要求      

采用冒泡排序、快速排序(可用STL)和哈希三种算法实现。分析并比较算法的执行效率。

实验开设方式

本实验开设方式为个人实验;

可以去HDU OJ上提交程序,比较返回的结果。或者自已造大数据测试。

实验思考

是否还有更快的求解算法。

个人评价

其实这个实验本身很简单,就是分析一下代码的时间复杂度,但是个人不建议使用oj在线平台来进行代码的时间测试,可能你提交相同的代码,因为测评机负载的不同,会出现时间的较大偏差。但是理论上也是肯定能看出o(nlogn)和o(n)的差别,但是像哈希排序这道题目几乎可以跑到o(n),你可能很难分清其跟nlogn的用时区别。

实验流程

编写三种不同排序方法的算法,其中快速排序使用qsor库函数,而不使用sort。
程序计时模块和输入输出模块均相同。
使用最新版本GCC,确保程序代码没有无用语句,并且以相同的编译命令来编译程序。

输入和计时模块:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <sstream>
#include <windows.h> 
using namespace std;
int a[100000000];
int main()
{	
	LARGE_INTEGER t1,t2,tc;
    QueryPerformanceFrequency(&tc);
    unsigned long long onems;
    //cout<<tc.QuadPart<<endl;
	onems=tc.QuadPart/1000000;
	//============================================
	int n,m,i;
	FILE *fp;
	fp=fopen("date.txt","r");
	fscanf(fp,"%d %d",&n,&m);
	for(i=0;i<n;i++)
		fscanf(fp,"%d",&a[i]);
	fclose(fp);
    QueryPerformanceCounter(&t1);//开始计时 
	///===========================================
	
	///===========================================
    QueryPerformanceCounter(&t2);
    cout<<"元素个数"<<n<<endl<<"前n大的数:"; 
	for(i=0;i<m;i++)
	{
		cout<<a[i]<<" "; 
	}
	cout<<endl;
    int time=(double)(t2.QuadPart-t1.QuadPart)/onems; 
    cout<<endl<<"程序用时 : "<<time/1000.0<<" 毫秒"<<endl;  
	return 0;
}

数据生成器

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <sstream>
#include <windows.h>
#include <random>
#include <ctime>
using namespace std;
int get_ran()
{
	int ans,minn;
	ans=((double)rand() / RAND_MAX) * 600000.0;
	minn=rand(); 
	if(ans>=500000)
		ans%=500000;
	if(minn%2==0)
		return ans;
	else
		return -ans;
}
int main()
{
    int n=5000,m=10;
    srand((unsigned)time(NULL)); 
	//cin>>n>>m;
	int i;
	freopen("date.txt","w",stdout);
	cout<<n<<" "<<m<<endl;
	for(i=0;i<n;i++)
		cout<<get_ran()<<endl;
	fclose(stdout);
	return 0;
}

排序代码:

快排:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <sstream>
#include <windows.h> 
using namespace std;
int a[100000000];
int cmp(const void * a, const void * b)
{
   return ( *(int*)b - *(int*)a );
}
int main()
{	
	LARGE_INTEGER t1,t2,tc;
    QueryPerformanceFrequency(&tc);
    unsigned long long onems;
    //cout<<tc.QuadPart<<endl;
	onems=tc.QuadPart/1000000;
	//============================================
	int n,m,i;
	FILE *fp;
	fp=fopen("date.txt","r");
	fscanf(fp,"%d %d",&n,&m);
	for(i=0;i<n;i++)
		fscanf(fp,"%d",&a[i]);
	fclose(fp);
    QueryPerformanceCounter(&t1);//开始计时 
	///===========================================
    qsort(a,n,sizeof(int),cmp);
	///===========================================
    QueryPerformanceCounter(&t2);
    cout<<"元素个数"<<n<<endl<<"前n大的数:"; 
	for(i=0;i<m;i++)
	{
		cout<<a[i]<<" "; 
	}
	cout<<endl;
    int time=(double)(t2.QuadPart-t1.QuadPart)/onems; 
    cout<<endl<<"程序用时 : "<<time/1000.0<<" 毫秒"<<endl;  
	return 0;
}

元素个数50000000
前n大的数:499984 499984 499984 499984 499984 499984 499984 499984 499984 499984

程序用时 : 4743.91 毫秒

冒泡排序 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <sstream>
#include <windows.h>
using namespace std;
int a[100000000];
int main()
{
	LARGE_INTEGER t1, t2, tc;
	QueryPerformanceFrequency(&tc);
	unsigned long long onems;
	//cout<<tc.QuadPart<<endl;
	onems = tc.QuadPart / 1000000;
	//============================================
	int n, m, i, j;
	FILE *fp;
	fp = fopen("date.txt", "r");
	fscanf(fp, "%d %d", &n, &m);
	for (i = 0; i < n; i++)
		fscanf(fp, "%d", &a[i]);
	fclose(fp);
	QueryPerformanceCounter(&t1); //开始计时
	///===========================================
	for (i = 0; i < n; i++)
	{
		for (j = 0; j + 1 < n - i; j++)
		{
			if (a[j] < a[j + 1])
			{
				swap(a[j], a[j + 1]);
			}
		}
	}
	///===========================================
	QueryPerformanceCounter(&t2);
	cout << "元素个数" << n << endl
		 << "前n大的数:";
	for (i = 0; i < m; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;
	int time = (double)(t2.QuadPart - t1.QuadPart) / onems;
	cout << endl
		 << "程序用时 : " << time / 1000.0 << " 毫秒" << endl;
	return 0;
}

元素个数100000
前n大的数:499966 499929 499929 499929 499929 499929 499911 499893 499874 499856

程序用时 : 27857.1 毫秒

哈希排序:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <sstream>
#include <windows.h>
using namespace std;
int a[100000000];
int hx[1000000]={0};
int main()
{
	LARGE_INTEGER t1, t2, tc;
	QueryPerformanceFrequency(&tc);
	unsigned long long onems;
	//cout<<tc.QuadPart<<endl;
	onems = tc.QuadPart / 1000000;
	//============================================
	int n, m, i, j;
	FILE *fp;
	fp = fopen("date.txt", "r");
	fscanf(fp, "%d %d", &n, &m);
	for (i = 0; i < n; i++)
		fscanf(fp, "%d", &a[i]);
	fclose(fp);
	QueryPerformanceCounter(&t1); //开始计时
	///===========================================
	for (i = 0; i < n; i++)
	{
		hx[a[i]+500000]++;
	}
	j=0;
	for(i=1000000;i>=0;i--)
	{
		while(hx[i]--)
		{
			a[j]=i-500000;
			j++;
		}
	}
	///===========================================
	QueryPerformanceCounter(&t2);
	cout << "元素个数" << n << endl
		 << "前n大的数:";
	for (i = 0; i < m; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;
	int time = (double)(t2.QuadPart - t1.QuadPart) / onems;
	cout << endl
		 << "程序用时 : " << time / 1000.0 << " 毫秒" << endl;
	return 0;
}

元素个数50000000
前n大的数:499984 499984 499984 499984 499984 499984 499984 499984 499984 499984

程序用时 : 337.808 毫秒

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值