实验十三排序算法的实现

发布于:2024-10-18 ⋅ 阅读:(7) ⋅ 点赞:(0)

实验十三排序算法的实现

一、【实验目的】
(1) 理解插入排序算法的实现过程;
(2)理解不同排序算法的时间复杂度及适用环境;
(3)了解算法性能测试的基本方法。

二、【实验内容】
(1)以下是一个通过随机数来测试排序算法运行时间的程序,中间留出了加入排序算法的部分。其中可以通过修改RANDNUM的值来更改测试的数据量:

#include "stdio.h"
#include <stdlib.h>
#include <time.h>
#define RANDNUM 10000 //随机数的个数
 
void main()
{ 
       int iRandNum[RANDNUM];//存放随机数
       clock_t first,second; //记录开始和结束时间(以毫秒为单位)
       int i;
          for(i=0;i<RANDNUM;i++)
       {//产生1万个随机数
          iRandNum[i]=rand()%RANDNUM;
       }
 
       first=clock(); //开始时间
       //此处加入排序程序
       second=clock();//结束时间
            //显示排序算法所用的时间
}

(2)从选择、交换、插入排序算法中任选至少3种排序算法(希尔排序、快速排序、堆排序三选二),在无序状态下进行多次运行,记录运行时间,并比较测试结果。

提示:在程序的实现过程中要用到以下函数,请大家在实验之前自学这几个函数的用法:
1)随机函数rand()
2) 时间函数clock()
实验参考界面如下(此界面测试数据仅选用了两种算法,提交的报告以实验要求为准。):

在这里插入图片描述

三、实验源代码

#include "stdio.h"
#include <stdlib.h>
#include <time.h>
#define RANDNUM 10000 //随机数的个数

typedef int keyType; 

typedef struct
{
	keyType key;
}ElemType; 

void InsertSort(int a[],int n)//用直接插入法对a[0]-a[n-1]排序 
{
	int i,j;
	int temp;
	for(i=0;i<n-1;i++)
	{
		temp=a[i+1];
		j=i;
		while(j>-1&&temp<a[j])
		{
			a[j+1]=a[j];
			j--;
		}
		a[j+1]=temp;
	}
}

//希尔排序 
void ShellSort(int x[],int n,int d[],int number)
//x为待排列数组,n为数组中元素个数,d[0]-d[number-1]为希尔增量值
//number为步长序列个数 
{
	int i,j,k,m,span;//span为增量 
	int temp;
	for(m=0;m<number;m++)//总共要进行number轮排序 
	{
		span=d[m];
		for(k=0;k<span;k++)
		{
			for(i=k;i+span<n;i+=span)
			{
				temp=x[i+span];
				j=i;
				while(j>-1&&temp<x[j])
				{
					x[j+span]=x[j];
					j-=span;
				}
				x[j+span]=temp;
			}
		 } 
	 } 
 } 
 
 //快速排序
 void QuickSort(int a[],int low,int high)
{
	int i,j;
	int temp;
	i=low;
	j=high;
	temp=a[low];
	while(i<j)
	{
		while(i<j&&temp<=a[j])
			j--;
		if(i<j)
		{
			a[i]=a[j];
			i++;
		}
		while(i<j&&a[i]<temp)
			i++;
		if(i<j)
		{
			a[j]=a[i];
			j--;
		}
	}
	a[i]=temp;
	if(low<i)
		QuickSort(a,low,i-1);//对左端子集合进行递归
	if(i<high)
		 QuickSort(a,j+1,high);//对右端子集合进行递归
} 

int main()
{ 
    int iRandNum[RANDNUM];//存放随机数
    clock_t first,second; //记录开始和结束时间(以毫秒为单位)
	int i;
    for(i=0;i<RANDNUM;i++)//产生1万个随机数
	{
    iRandNum[i]=rand()%RANDNUM;
    }
    first=clock(); //开始时间
    InsertSort(iRandNum,RANDNUM);//直接插入排序 
    second=clock();//结束时间
    printf("直接插入排序:%lf seconds",(double)(second-first)/CLOCKS_PER_SEC);//显示排序算法所用的时间
    printf("\n"); 
    int d[]={5000,2500,1250,625,312,156,78,39,19,9,4,2,1};
	int number=13; 
    first=clock(); 
    ShellSort(iRandNum,RANDNUM,d,number);//希尔排序 
    second=clock();
    printf("希尔排序:%lf seconds",(double)(second-first)/CLOCKS_PER_SEC);
    printf("\n");  
    int low=0;
    int high=RANDNUM;
    first=clock(); 
    QuickSort(iRandNum,low,high);//快速排序 
    second=clock();
    printf("快速排序:%lf seconds",(double)(second-first)/CLOCKS_PER_SEC);
   
    return 0;
}

四、实验结果
在这里插入图片描述

五、实验总结
1.碰到的问题和解决办法。
当使用 clock 函数测量时间时,它返回的是 CPU 所花费的时钟周期数,而不是实际的毫秒数。因此,将 clock 函数返回的结果直接除以 1000 可能会导致时间显示不准确
在 C语言中,clock 函数返回的时钟周期数的单位是CLOCKS PER SEC,它表示每秒钟的时钟周期数。因此,为了将时钟周期数转换为秒,你应该将 clock 函数返回的结果除以 CLOCKS PER SEC 而不是直接除以 1000。这样可以确保时间的显示更加准确。
所以,应该使用((double)(second - first) / CLOCKS PER SEC 来计算排序所用的时间,而不是(double)(second - first)/1000 。
2.你的收获。

快速排序算法:
首先,函数 QuickSort 接受一个整型数组 a[],以及两个整数参数 low 和 high,这两个参数表示数组的起始位置和结束位置。
在函数内部,定义了三个整型变量 i、j 和 temp,i 用于标记当前的位置,j 用于标记结束位置,temp 用于保存基准值。
选择数组中的第一个元素作为基准值,保存在 temp 中。
使用两个指针 i 和 j 分别从数组的两端向中间移动,以便找到需要交换的元素。
在 while 循环中,首先从右向左移动指针 j,直到找到一个小于等于基准值的元素。然后从左向右移动指针 i,直到找到一个大于基准值的元素。
交换 a[i] 和 a[j] 的值,然后继续移动指针 i 和 j,直到它们相遇。
将基准值 temp 放置在指针 i 所指向的位置,此时数组被分成了两部分,左边的部分都小于等于基准值,右边的部分都大于基准值。
接着对左右两部分分别进行递归调用 QuickSort 函数,直到排序完成。

希尔排序算法:

  1. 首先,函数 ShellSort 接受一个整型数组 x[],以及三个整数参数n、d[] 和 number,其中 n 表示数组中元素的个数,d[]表示希尔增量值,number表示步长序列的个数。
  2. 在函数内部,定义了五个整型变量 i、j、k、m和 span ,其中 i 用于标记当前的位置, j 用于标记前一个位置, k 用于标记起始位置, m 用于标记当前轮数, span 用于保存当前增量值。
  3. 在外层循环中,遍历所有的增量值,总共要进行 number 轮排序。
  4. 在内层循环中,遍历所有的子序列,每个子序列的起始位置为 k ,增量值为 span 。
  5. 对于每个子序列,使用插入排序算法进行排序。将第 i+span 个元素与前面的元素依次比较,如果小于前面的元素,则将前面的元素后移,直到找到合适的位置插入当前元素。
  6. 对于每个子序列,重复上述步骤,直到排序完成。
  7. 对下一个增量值进行排序,直到所有的增量值都被排序完成。

网站公告

今日签到

点亮在社区的每一天
去签到