实现功能:
利用随机函数产生N个随机整数(20000以上),对这些数进行多种方法进行排序。
要求:
1) 至少采用三种方法实现上述问题求解(提示,可采用的方法有插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序)。并把排序后的结果保存在不同的文件中。
2) 统计每一种排序方法的性能(以上机运行程序所花费的时间为准进行对比),找出其中两种较快的方法。
3) 如果采用4种或4种以上的方法者,可适当加分。
利用随机函数产生30000个随机数,并将这些数存入txt文件中的代码如下:
#define N 30000
void write() //随机产生30000个数,并将这些数存放在data.txt文件中
{
FILE* fp=fopen("data0.txt","w");
for(int i=1;i<=N;i++)
{
fprintf(fp,"%d ",rand());
if(i%10==0)
fprintf(fp,"\n");
}
fclose(fp);
}
从文件中读取数据,并且输出的代码如下:
//从文件中读入数据存入数组a
int readData(int a[], int n,char *f ) //函数返回成功读入放入数据个数
{
FILE *fp;
int i;
fp=fopen(f,"r");
if (fp==NULL){
fclose(fp);
return 0;
}
else
{
for (i=0; ifscanf(fp,"%d",&a[i]);
fclose(fp);
return i;
}
}
void output(int a[],int n) //输出数组的内容
{
int i;
printf("原数组的内容是:");
for (i=0; iif (i%10==0)
printf("\n");
printf("%7d",a[i]);
}
printf("\n");
}
各种排序算法可以看下我之前发表的博客;
计算各算法的时间消耗的代码,以选择排序算法为例,如下:
#include
double time1;
clock_t start,finish;
start=clock();
SelectSort(a,N);
finish=clock();
time1=(double)(finish-start)/CLOCKS_PER_SEC;
cout<<"选择排序的耗时:"<"秒"<
将各种排序算法的结果存入txt文件中的代码,以选择排序为例,如下:
SelectSort(a,N);
FILE* fp1;
fp1=fopen("data1.txt","w");
for(int i=0;i"%d \t",a[i]);
}
fclose(fp1);
整体代码如下:(水平低,仅供参考)
无堆排序的原因是堆排序读取的数组第一个数据无作用,为了课设结果的整体性所以去掉,堆排序可以参考之前我发表的博客;
#include
#include
#include
#include
#include
#include
using namespace std;
#define N 30000
void write() //随机产生30000个数,并将这些数存放在data.txt文件中
{
FILE* fp=fopen("data0.txt","w");
for(int i=1;i<=N;i++)
{
fprintf(fp,"%d ",rand());
if(i%10==0)
fprintf(fp,"\n");
}
fclose(fp);
}
//从文件中读入数据存入数组a
int readData(int a[], int n,char *f ) //函数返回成功读入放入数据个数
{
FILE *fp;
int i;
fp=fopen(f,"r");
if (fp==NULL){
fclose(fp);
return 0;
}
else
{
for (i=0; ifscanf(fp,"%d",&a[i]);
fclose(fp);
return i;
}
}
void output(int a[],int n) //输出数组的内容
{
int i;
printf("原数组的内容是:");
for (i=0; iif (i%10==0)
printf("\n");
printf("%7d",a[i]);
}
printf("\n");
}
void SelectSort(int a[],int n) //选择排序
{
int mix,temp;
for(int i=0;i1;i++) //每次循环数组,找出最小的元素,放在前面,前面的即为排序好的
{
mix=i; //假设最小元素的下标
for(int j=i+1;j//将上面假设的最小元素与数组比较,交换出最小的元素的下标
if(a[j]//若数组中真的有比假设的元素还小,就交换
if(i!=mix)
{
temp=a[i];
a[i]=a[mix];
a[mix]=temp;
}
}
}
void bubleSort(int a[],int n)//冒泡排序
{
int temp;
//运用两个for循环,每次取出一个元素跟数组的其它元素比较,将最大的元素排到最后
for(int i=0;i1;i++)
{
//外循环一次,就排好一个数,并放在后面,所以比较前面n-i-1个元素即可
for(int j=0;j1;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
void bInsertSort(int a[],int n) //插入排序
{
int low,high,mid;
int temp;
for(int i=1;i0;
//把a[i]元素插入到它的前面a[0--(n-1)]中
temp=a[i];
high=i-1;
while(low<=high) //该while是折半优化算法,缩小a[i]的范围
{
mid=(low+high)/2;
if(a[mid]>temp)
high=mid-1;
else
low=mid+1;
}
int j=i;
while((j>low)&&(a[j-1]>temp)) //让a与已经排好的数组的各元素比较,小的放前面
{
a[j]=a[j-1];
--j;
}
a[low]=temp;
}
}
int findPos(int a[],int low,int high)
{
//将小于t的元素赶到t的左边,大于t的元素赶到t的右边
int t=a[low];
while(lowwhile(low=t)
high--;
a[low]=a[high];
while(low//返回此时t在数组中的位置
return low;
}
//在数组中找一个元素,对于大于该元素和小于该元素的两个数组进行再排序,
//再对两个数组分为4个数组,再排序,直到最后每组只剩下一个元素为止
void quickSort(int a[],int low,int high) //快速排序
{
if(low>high)
return ;
int pos=findPos(a, low, high);
quickSort(a, low, pos-1);
quickSort(a, pos+1, high);
}
void shellSort(int *a,int n) //希尔排序
{
int key,j;
for(int step=n/2;step>0;step/=2) //将数组按照step分组,不断二分到每组只剩下一个元素
{
for(int i=step;i//将每组中的元素排序,小的在前面
{
key=a[i];
for(j=i-step;j>=0 && key//和上面的for循环一起,将组中小的元素换到数组的前面
}
}
}
void merge(int a[],int low,int mid,int high)
{
int i,k;
//定义一个临时数组存放传进来的无序数组排好序之后的数组
int *temp=(int *)malloc((high-low+1)*sizeof(int));
//将无序数组分成两个序列
int left_low=low;
int left_high=mid;
int right_low=mid+1;
int right_high=high;
//将两个序列比较排序,小的排前
for(k=0;left_low<=left_high && right_low<=right_high;k++)
{
if(a[left_low]<=a[right_low])
temp[k]=a[left_low++];
else
temp[k]=a[right_low++];
}
//左序列如果有剩下元素未排序,加到临时数组的末尾
if(left_low<=left_high)
{
for(i=left_low;i<=left_high;i++)
temp[k++]=a[i];
}
//右序列如果有剩下元素未排序,加到临时数组的末尾
if(right_low<=right_high)
{
for(i=right_low;i<=right_high;i++)
temp[k++]=a[i];
}
//将排好序的小分组转移到原数组中
for(i=0;i1;i++)
{
a[low+i]=temp[i];
}
free(temp);
}
void mergeSort(int a[],int first,int last)//归并排序
{
int mid=0;
//将数组不停的二分分组再组合,直到每组只剩下一个元素
if(first2;
mergeSort(a, first, mid);
mergeSort(a, mid+1, last);
merge(a,first,mid,last);
}
}
//该函数的作用是找出num的pos位数的数字(比如:23的个位数数字是3)
int getNumPos(int num,int pos)
{
int i;
int temp=1;
for(i=0;i1;i++)
temp*=10;
return (num/temp)%10;
}
void radixSort(int a[],int n) //基数排序
{
int i,j,k,pos,num,index;
//这几句话是创建一个从0-9(行)× (n+1)(列)的网格,第一列从上往下是0-9,第二列是该行包含的元素个数,默认为0个
int *radixArrays[10];
for(i=0;i<10;i++)
{
radixArrays[i]=(int *)malloc(sizeof(int)*(n+1));
radixArrays[i][0]=0;
}
//pos最大为31为数,计算机能承受的最大范围了
for(pos=1;pos<=31;pos++)
{
//该for循环是将数组的元素按照位数(pos)的值放进网格内
for(i=0;i0];
radixArrays[num][index]=a[i];
}
//该for循环是将上面的for循环已经按照某个位数(pos)排列好的元素存入数组
for(i=0,j=0;i<10;i++)
{
for(k=1;k<=radixArrays[i][0];k++)
a[j++]=radixArrays[i][k];
//清空网格,以便给下个位数排列
radixArrays[i][0]=0;
}
}
}
int main()
{
write();
int n,a[N];
n=readData(a,N,"data0.txt");
output(a,n);
cout<<"********************"<cout<<"1.选择排序 "<cout<<"2.冒泡排序 "<cout<<"3.插入排序 "<cout<<"4.快速排序 "<cout<<"5.希尔排序 "<cout<<"6.归并排序 "<cout<<"7.基数排序 "<cout<<"********************"<cout<<"请输入你的选择:"<double time1,time2,time3,time4,time5,time6,time7;
clock_t start,finish;
char c=getchar();
switch(c)
{
case '1':
cout<<"选择排序:"<double)(finish-start)/CLOCKS_PER_SEC;
for(int i=0;icout<" "<<"\t";
cout<cout<<"选择排序的耗时:"<"秒"<"data1.txt","w");
for(int i=0;ifprintf(fp1,"%d \t",a[i]);
}
fclose(fp1);
break;
case '2':
cout<<"冒泡排序:"<double)(finish-start)/CLOCKS_PER_SEC;
for(int i=0;icout<" "<<"\t";
cout<cout<<"冒泡排序的耗时:"<"秒"<"data2.txt","w");
for(int i=0;ifprintf(fp2,"%d \t",a[i]);
}
fclose(fp2);
break;
case '3':
cout<<"插入排序:"<double)(finish-start)/CLOCKS_PER_SEC;
for(int i=0;icout<" "<<"\t";
cout<cout<<"插入排序的耗时:"<"秒"<"data3.txt","w");
for(int i=0;ifprintf(fp3,"%d \t",a[i]);
}
fclose(fp3);
break;
case '4':
cout<<"快速排序:"<0, N-1);
finish=clock();
time4=(double)(finish-start)/CLOCKS_PER_SEC;
for(int i=0;icout<" "<<"\t";
cout<cout<<"快速排序的耗时:"<"秒"<"data4.txt","w");
for(int i=0;ifprintf(fp4,"%d \t",a[i]);
}
fclose(fp4);
break;
case '5':
cout<<"希尔排序:"<double)(finish-start)/CLOCKS_PER_SEC;
for(int i=0;icout<" "<<"\t";
cout<cout<<"希尔排序的耗时:"<"秒"<"data5.txt","w");
for(int i=0;ifprintf(fp5,"%d \t",a[i]);
}
fclose(fp5);
break;
case '6':
cout<<"归并排序:"<0, N-1);
finish=clock();
time6=(double)(finish-start)/CLOCKS_PER_SEC;
for(int i=0;icout<" "<<"\t";
cout<cout<<"归并排序的耗时:"<"秒"<"data6.txt","w");
for(int i=0;ifprintf(fp6,"%d \t",a[i]);
}
fclose(fp6);
break;
case '7':
cout<<"基数排序:"<double)(finish-start)/CLOCKS_PER_SEC;
for(int i=0;icout<" "<<"\t";
cout<cout<<"基数排序的耗时:"<"秒"<"data7.txt","w");
for(int i=0;ifprintf(fp7,"%d \t",a[i]);
}
fclose(fp7);
break;
default:
cout<<"输入错误!请重新输入!";
}
return 0;
}