题目如下:
选择排序法对于小数组来说比归并排序快,尽管当数组变大时,情况相反。如果你想设计一个函数SortIntegerArray,使之适应于各种大小的数组,那么可以把两种策略结合起来,对大数组用合并排序,对小数组使用选择排序。用这种方法重新实现函数SortIntegerArray,那么该如何选择区分大小数组的那个分界点呢?
要求:从一个数据文件中读入N个整数(N<=100000),且把结果保存到另一个文本文件中,并显示排序所用的时间。
//merselsort.h
//
//merselsort.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
//定义计时参数
LARGE_INTEGER nFreq, t11, t12, t21, t22;
double dt, dt1, dt2;
//归并排序
void mergesort(long *list, long length)
{
long i, left_min, left_max, right_min, right_max, next;
long *tmp = (long*)malloc(sizeof(long) * length);
if (tmp == NULL)
{
fputs("ERROR!\n", stderr);
abort();
}
for (i = 1; i < length; i *= 2) // i为步长,1,2,4,8……
{
for (left_min = 0; left_min < length - i; left_min = right_max)
{
right_min = left_max = left_min + i;
right_max = left_max + i;
if (right_max > length)
right_max = length;
next = 0;
while (left_min < left_max && right_min < right_max)
tmp[next++] = list[left_min] > list[right_min] ? list[right_min++] : list[left_min++];
while (left_min < left_max)
list[--right_min] = list[--left_max];
while (next > 0)
list[--right_min] = tmp[--next];
}
}
free(tmp);
}
//选择排序
void selectsort(long *array, long arrLen)
{
long index, k, i, n, temp;
for (k = 0; k<arrLen; k++) {
index = k;
for (i = k + 1; i<arrLen; i++)
if (array[i]< array[index]) index = i;
temp = array[index];
array[index] = array[k];
array[k] = temp;
}
}
//融合排序(测试两种排序方法排序时间并比较算法效率)
void SortIntegerArray(long *array1, long *array2, long arrLen, char ch[])
{
//选择排序
QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&t11);//计时开始
selectsort(array1, arrLen);
QueryPerformanceCounter(&t12);//计时结束
dt1 = (t12.QuadPart - t11.QuadPart) / (double)nFreq.QuadPart;
//归并排序
QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&t21);//计时开始
mergesort(array2, arrLen);
QueryPerformanceCounter(&t22);//计时结束
dt2 = (t22.QuadPart - t21.QuadPart) / (double)nFreq.QuadPart;
//比较算法效率
if (dt1 >= dt2)
{
dt = dt1;
strcpy(ch, "Merge sort");
}
else
{
dt = dt2;
strcpy(ch, "Selection sort");
}
}
//data.h
//
//data.h
#include <stdio.h>
//不重复随机数据生成
void Randin(long *array, long arrLen)
{
long i, j, t;
for (i = 0; i < arrLen; i++)
{
t = rand() % 100000;
for (j = 0; j < i; j++)
if (array[j] == t)
break;
if (j == i)//不重复
array[i++] = t;//记录随机数。
}
}
//输出数组元素
void PrintArray(long *array, long arrLen)
{
long i, count = 0;
for (i = 0; i < arrLen; i++)
{
if (count == 10)//控制格式,每输出十个数换行
{
printf("\n");
count = 0;
}
printf("%6ld", array[i]);
count++;
}
printf("\n");
}
//control.h
//
//control.h
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
void con()
{
printf("\n>> Press any key to continue!");
getch();
system("cls");
}
//merselsort.c
//
//merselsort.c
#include "merselsort.h"
#include "data.h"
#include "control.h"
int main()
{
int a;//控制结果是否输出
long arrLen, c, i; //arrLen为数组的长度
long *array1, *array2; //数组指针
char ch[50];//存储应选择的排序方法
printf(">> Please set the length of the array(arrLen<100000!):\n>> arrLen=");
scanf("%ld", &arrLen);//获得数组长度
FILE *fpWrite = fopen("data1.txt", "w");
if (fpWrite == NULL)
{
return 0;
}
// 动态分配内存空间,如果失败就退出程序
array1 = (long*)malloc(arrLen * sizeof(long));
array2 = (long*)malloc(arrLen * sizeof(long));
if (!array1 || !array2) {
printf(">> Failed to create an array!\n");
exit(1);
}
// 通过随机数向内存中写入数据
long j, t;
for (i = 0; i < arrLen; )
{
t = rand() % 100000;
for (j = 0; j < i; j++)
if (array1[j] == t)
break;
if (j == i)//不重复
array1[i++] = t;//记录随机数。
}
//生成的数组
printf("\n>> Output the array elements before sorting?(>> Output array element please enter 1, skip please enter any value!)\n");
printf(">> Please enter your selection:");
scanf("%d", &a);
if (a == 1)
{
printf(">> The array before sorting:\n");
PrintArray(array1, arrLen);
}
//向文件中写入数据
for (i = 0; i<arrLen; i++)
fprintf(fpWrite, "%ld ", array1[i]);
fclose(fpWrite);
//从文件中读数据并存到另一个数组
FILE *fpRead = fopen("data1.txt", "r");
if (fpRead == NULL)
{
return 0;
}
for (i = 0; i<arrLen; i++)
{
fscanf(fpRead, "%ld ", &array2[i]);
}
//融合排序
SortIntegerArray(array1, array2, arrLen, ch);
//将结果保存在另一个文件中
FILE *fpWrite2 = fopen("data2.txt", "w");
if (fpWrite == NULL)
{
return 0;
}
for (i = 0; i<arrLen; i++)
fprintf(fpWrite2, "%ld ", array2[i]);
fclose(fpWrite2);
//输出排序结果
printf("\n>> Output the array elements after sorting?(>> Output array element please enter 2, skip please enter any value!)\n");
printf(">> Please enter your selection:");
scanf("%d", &a);
if (a == 2)
{
printf(">> The array after sorting:\n");
PrintArray(array2, arrLen);
}
//控制清屏
con();
//释放内存
free(array1);
free(array2);
//输出排序方法及排序时间
printf(">> The sorting algorithm that should be selected : %s\n\n", ch);
printf(">> Sorting time: %f ms\t", dt);
return 0;
}