1.任务:
[问题描述]
利用随机函数产生10个样本,每个样本有50000个随机整数(并使第一个样本是正序,第二个样本是逆序),利用直接插入排序、希尔排序,冒泡排序、快速排序、选择排序、堆排序,归并排序、基数排序8种排序方法进行排序(结果为由小到大的顺序),并统计每一种排序算法对不同样本所耗费的时间。
[基本要求]
(1)原始数据存在文件中,用相同样本对不同算法进行测试;
(2)屏幕显示每种排序算法对不同样本所花的时间;
2.采用的数据结构:
采用顺序结构和各种排序
3.算法设计思想:
直接插入排序:每次从原数组中提取一个记录插入已经排好的有序表。空间复杂度:S(n)=O(1),时间复杂度:T(n)=O(n^2)。
希尔排序:将整个待排记录序列分成若干个子序列,依次进行插入排序,当整个序列的记录都基本有序后,再进行一次直接插入排序。空间复杂度:S(n)=O(1),时间复杂度:T(n)=O(n^1.5)。
冒泡排序:将第n-1个和第n个记录进行比较,如果为逆序则交换。空间复杂度:S(n)=O(1),时间复杂度:T(n)=O(n^2)。
快速排序:选取一个记录作为枢轴,其余记录与它比较,将比他小和比他大的元素分置于该元素两端,再对这两部分分别进行快速排序,直至完全有序。空间复杂度:S(n)=O(logn),时间复杂度:T(n)=O(nlogn)。
简单选择排序:每一趟都选取未排序记录中的最小值,并与未排序记录中的第一个元素进行交换。空间复杂度:S(n)=O(1),时间复杂度:T(n)=O(n^2)。
堆排序:建立大顶堆,即使每一个根节点都大于等于其左右子树。将大顶堆第一个元素与最后一个记录交换,去除最后一个记录,对大顶堆重新进行筛选,直至完全有序。空间复杂度:S(n)=O(),时间复杂度:T(n)=O()。
归并排序:将原序列中的每个记录都看作单独的序列,进行两两归并,得到n/2个序列,继续归并,重复以上步骤,直至得到一个长度为n的有序序列为止。空间复杂度:S(n)=O(n),时间复杂度:T(n)=O()。
基数排序:将记录按照个位对于分配到0-9十个队列中,按0-9收集10个队列的记录,再按照十位、百位…(即权值从低到高)重复。空间复杂度:S(n)=O(n),时间复杂度:T(n)=O(dn)。
4.源程序:
#include <iostream>
#include <fstream>
#include <time.h>
#include <cstdlib>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sstream>
#include <queue>
using namespace std;
int a[50000];
void writedata() //在十个文档中生成随机数据
{
ofstream outfile;
outfile.open("1.txt");
if(outfile)
{
for(int i=0;i<50000;i++)
{
a[i]=i-17250;
outfile<<a[i]<<" ";
}
}
else
{
printf("文件打开失败!");
}
outfile.close();
outfile.open("2.txt");
if(outfile)
{
for(int i=0;i<50000;i++)
{
a[i]=32767-i;
outfile<<a[i]<<" ";
}
}
else
{
printf("文件打开失败!");
}
outfile.close();
for(int i=3;i<=10;i++)
{
string filename;
stringstream ss;
ss<<i;
ss>>filename;
filename=filename+".txt";
char f[10];
strcpy(f,filename.c_str());
ofstream outfile;
outfile.open(f);
for(int i=0;i<50000;i++)
{
a[i]=rand()%65536-32768;
outfile<<a[i]<<" ";
}
outfile.close();
}
}
int delta()
{
unsigned long start,end;
start=clock();
for(int i=3;i<=10;i++)
{
ifstream infile;
string filename;
stringstream ss;
ss<<i;
ss>>filename;
filename=filename+".txt";
char f[10];
strcpy(f,filename.c_str());
infile.open(f);
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
}
end=clock();
return end-start;
}
int InsertSort(int a[50000]) //插入排序
{
int temp;
for(int i=1;i<50000;i++)
{
temp=a[i];
for(int j=i;j>0;j--)
{
if(temp<a[j-1])
{
a[j]=a[j-1];
}
else
{
a[j]=temp;
break;
}
}
}
return 1;
}
int ShellSort(int a[50000]) //希尔排序
{
for(int k=5;k>=1;k=k-2)
{
int temp;
for(int i=k+1;i<50000;i++)
{
temp=a[i];
for(int j=i;j>0;j=j-k)
{
if(temp<a[j-k])
{
a[j]=a[j-k];
}
else
{
a[j]=temp;
break;
}
}
}
}
}
int BubbleSort(int a[50000]) //冒泡排序
{
for(int i=0;i<50000;i++)
{
int boolean=0;
for(int j=1;j<50000-i;j++)
{
if(a[j-1]>a[j])
{
int t;
t=a[j];
a[j]=a[j-1];
a[j-1]=t;
boolean=1;
}
}
if(boolean==0)
{
return 1;
}
}
return 1;
}
int QuickSort(int a[],int low,int high) //快速排序
{
if(low>high)
{
return 1;
}
int i=low,j=high;
int k=a[(low+high)/2];
while(i<=j)
{
while(a[j]>k)
{
j--;
}
while(a[i]<k)
{
i++;
}
if(i<=j)
{
int temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
i++;
j--;
}
}
if(low<j)
{
QuickSort(a,low,j);
}
if(high>i)
{
QuickSort(a,i,high);
}
}
int SelectSort(int a[50000]) //选择排序
{
for(int i=0;i<49999;i++)
{
int min=a[i];
int k=i;
for(int j=i+1;j<50000;j++)
{
if(a[j]<min)
{
min=a[j];
k=j;
}
}
if(k!=i)
{
min=a[k];
a[i]=a[k];
a[k]=a[i];
}
}
return 1;
}
void HeapAdjust(int a[50000],int low,int high) //堆调整
{
int temp=a[low];
int i=low,j=2*i;
while(j<=high)
{
if(j+1<=high && a[j]<a[j+1])
{
j++;
}
if(temp>=a[j])
{
break;
}
a[i]=a[j];
i=j;
j=2*i;
}
a[i]=temp;
}
int HeapSort(int a[50000]) //堆排序
{
for(int i=25000;i>=0;i--)
{
HeapAdjust(a,i,49999);
}
for(int i=49999;i>0;i--)
{
int t;
t=a[i];
a[i]=a[0];
a[0]=t;
HeapAdjust(a,0,i-1);
}
}
int b[50000];
void Merge(int a[],int low,int mid,int high)
{
int i=low,j=mid+1;
int k=0;
while(i<=mid && j<=high)
{
if(a[i]<=a[j])
{
b[k++]=a[i++];
}
else
{
b[k++]=a[j++];
}
}
while(i<=mid)
{
b[k++]=a[i++];
}
while(j<=high)
{
b[k++]=a[j++];
}
k=0;
for(int i=low;i<=high;i++)
{
a[i]=b[k];
k++;
}
}
int MergeSort(int a[50000]) //归并排序
{
for(int len=1;len<=50000;len=len*2)
{
int i=0;
while(i+2*len<=50000)
{
Merge(a,i,i+len-1,i+2*len-1);
i=i+2*len;
}
if(i+len<50000)
{
Merge(a,i,i+len-1,49999);
}
}
return 1;
}
int RadixSort(int a[50000]) //基数排序
{
long int b[50000];
queue<long int> Q[10];
int radix=1;
for(int i=1;i<=5;i++)
{
radix*=10;
for(int i=0;i<50000;i++)
{
b[i]=a[i]+32768;
int x;
x=(b[i]%radix)/(radix/10);
Q[x].push(b[i]);
}
int m=0;
for(int i=0;i<10;i++)
{
while(Q[i].empty()==0)
{
a[m++]=Q[i].front()-32768;
Q[i].pop();
}
}
}
}
int main()
{
srand((int)time(0));
writedata();
unsigned long start;
unsigned long end;
ifstream infile;
printf("\n 排序方式\t\t升序文件排序时间(ms)\t\t降序文件排序时间(ms)\t\t随机数据平均时间(ms)\n");
printf(" __________________________________________________________________________________________________________________\n\n");
//插入排序输出
printf(" 插入排序\t\t\t");
infile.open("1.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
InsertSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
infile.open("2.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
InsertSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
start=clock();
for(int i=3;i<=10;i++)
{
string filename;
stringstream ss;
ss<<i;
ss>>filename;
filename=filename+".txt";
char f[10];
strcpy(f,filename.c_str());
infile.open(f);
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
InsertSort(a);
}
end=clock();
cout<<(end-start-delta())/8<<"\t";
printf("\n\n");
//希尔排序输出
printf(" 希尔排序\t\t\t");
infile.open("1.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
ShellSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
infile.open("2.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
ShellSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
start=clock();
for(int i=3;i<=10;i++)
{
string filename;
stringstream ss;
ss<<i;
ss>>filename;
filename=filename+".txt";
char f[10];
strcpy(f,filename.c_str());
infile.open(f);
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
ShellSort(a);
}
end=clock();
cout<<(end-start-delta())/8<<"\t";
printf("\n\n");
//冒泡排序输出
printf(" 冒泡排序\t\t\t");
infile.open("1.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
BubbleSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
infile.open("2.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
BubbleSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
int t=0;
for(int i=3;i<=10;i++)
{
string filename;
stringstream ss;
ss<<i;
ss>>filename;
filename=filename+".txt";
char f[10];
strcpy(f,filename.c_str());
infile.open(f);
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
BubbleSort(a);
end=clock();
t+=end-start;
}
cout<<t/8<<"\t";
printf("\n\n");
//快速排序输出
printf(" 快速排序\t\t\t");
infile.open("1.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
QuickSort(a,0,49999);
end=clock();
cout<<end-start<<"\t\t\t\t";
infile.open("2.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
QuickSort(a,0,49999);
end=clock();
cout<<end-start<<"\t\t\t\t";
start=clock();
for(int i=3;i<=10;i++)
{
string filename;
stringstream ss;
ss<<i;
ss>>filename;
filename=filename+".txt";
char f[10];
strcpy(f,filename.c_str());
infile.open(f);
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
QuickSort(a,0,49999);
}
end=clock();
cout<<(end-start-delta())/8<<"\t";
printf("\n\n");
//选择排序输出
printf(" 选择排序\t\t\t");
infile.open("1.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
SelectSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
infile.open("2.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
SelectSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
start=clock();
for(int i=3;i<=10;i++)
{
string filename;
stringstream ss;
ss<<i;
ss>>filename;
filename=filename+".txt";
char f[10];
strcpy(f,filename.c_str());
infile.open(f);
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
SelectSort(a);
}
end=clock();
cout<<(end-start-delta())/8<<"\t";
printf("\n\n");
//堆排序
printf(" 堆排序\t\t\t");
infile.open("1.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
HeapSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
infile.open("2.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
HeapSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
start=clock();
for(int i=3;i<=10;i++)
{
string filename;
stringstream ss;
ss<<i;
ss>>filename;
filename=filename+".txt";
char f[10];
strcpy(f,filename.c_str());
infile.open(f);
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
HeapSort(a);
}
end=clock();
cout<<(end-start-delta())/8<<"\t";
printf("\n\n");
//归并排序
printf(" 归并排序\t\t\t");
infile.open("1.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
MergeSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
infile.open("2.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
MergeSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
start=clock();
for(int i=3;i<=10;i++)
{
string filename;
stringstream ss;
ss<<i;
ss>>filename;
filename=filename+".txt";
char f[10];
strcpy(f,filename.c_str());
infile.open(f);
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
MergeSort(a);
}
end=clock();
cout<<(end-start-delta())/8<<"\t";
printf("\n\n");
//基数排序
printf(" 基数排序\t\t\t");
infile.open("1.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
RadixSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
infile.open("2.txt");
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
start=clock();
RadixSort(a);
end=clock();
cout<<end-start<<"\t\t\t\t";
start=clock();
for(int i=3;i<=10;i++)
{
string filename;
stringstream ss;
ss<<i;
ss>>filename;
filename=filename+".txt";
char f[10];
strcpy(f,filename.c_str());
infile.open(f);
for(int i=0;i<50000;i++)
{
infile>>a[i];
}
infile.close();
RadixSort(a);
}
end=clock();
cout<<(end-start-delta())/8<<"\t";
printf("\n\n");
return 0;
}
5.源程序测试数据及结果:
排序算法比较测试结果
6.存在问题和解决方法:
在不同排序算法下对于十个文件的分别时间调用部分写的重复性较高,过于繁琐,可以考虑寻找共同点进行循环等方式的处理。同时,在冒泡排序时间中,按理论而言,降序文件所需的时间应是最高的,但事实上随机数据的平均时间却比降序文件所用的时间更长。