融合选择法和归并法的排序算法实现及效率分析(C语言)

题目如下:
选择排序法对于小数组来说比归并排序快,尽管当数组变大时,情况相反。如果你想设计一个函数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;
}

猜你喜欢

转载自blog.csdn.net/qq_42073370/article/details/82532109
今日推荐