c语言数据结构课设排序算法比较

此段代码针对冒泡排序,选择排序,希尔排序,插入排序,快速排序,基数排序,堆排序进行比较
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define M 10 //排序多少条,可自行改变
#define WIDTH 5 //被排序元素的最大位数,可以排100000以内的
#define MAXK 10 //位数划分基于的基数,10表示为10进制划分

typedef int ElementType;
void SetFigure(int *arr, int len)
{
FILE *fp=fopen(“rand.txt”,“w”); //生成随机数,并写入文件

int i;
srand(time(NULL));
for (i = 0; i<len; i++)
{
arr[i]=rand();
fprintf(fp,"%d ",arr[i]);
}
fclose(fp);
}

void GetFigure(int *arr, int len) //读出随机数,写入arr[]
{
FILE *fp=fopen(“rand.txt”,“r”);
int i;
for (i = 0; i < len; i++)
{
fscanf(fp,"%d ",arr + i);
}
fclose(fp);
}

void Print(int *arr,int len) //输出排完的数据
{
int i;
for(i=0;i<len;i++)
{
printf(" %d ",arr[i]);
}

}

void swap01(int *arr, int i, int j) //交换两个变量的值
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}

void Bubbling(int *arr, int len) //冒泡排序
{
int i;
int j;
int temp;

for(i = 0; i < len - 1; i++)
{
	for(j = 0; j < len - 1 - i; j++)
	{
		if(arr[j] > arr[j + 1])
		{
			temp = arr[j];
			arr[j] = arr[j + 1];
			arr[j + 1] = temp;
		}
	}
}

}

void SelectionSort(int arr, int len) // O(nn) 选择排序
{
int i = 0;
int j = 0;
int k = -1;

for(i=0; i<len; i++)
{
	k = i; //寻找最小元素的下标
	for(j=i+1; j<len; j++)
	{
		if( arr[j] < arr[k] ) //开始寻找最小元素的下标
		{
			k = j;	
		}
	}
	swap01(arr, i, k);
}

}

void InertionSort(int arr, int len) // O(nn) 直接插入排序
{
int i = 0;
int j = 0;
int k = -1;
int temp = -1;

for(i=1; i<len; i++)
{
	k = i; //待插入位置
	temp = arr[k];

	for(j=i-1; (j>=0) && (arr[j]>temp); j--)
	{ 
		arr[j+1] = arr[j]; //元素后移
		k = j; //k需要插入的位置
	}

	arr[k] = temp;//元素插入
}

}

void ShellSort(int *arr, int len) //希尔排序
{
int i = 0;
int j = 0;
int k = -1;
int temp = -1;
int gap = len;
do
{

	gap = gap / 3 + 1;   //O(n 1.3)

	for(i=gap; i<len; i+=gap)
	{
		k = i;
		temp = arr[k];

		for(j=i-gap; (j>=0) && (arr[j]>temp); j-=gap)
		{
			arr[j+gap] = arr[j];
			k = j;
		}

		arr[k] = temp;
	}

}while( gap > 1 );

}

void swap1(int *arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//划分过程 第一个元素当枢轴,分成2个有效子序列
int partition(int *arr, int low, int high)
{
int pv = arr[low];

while( low < high )
{
	while( (low < high) && (arr[high] >= pv) )
	{
		high--; //比基准大,本来就在右边,所以high前移动
	}
	swap1(arr, low, high);
	while( (low < high) && (arr[low] <= pv) )
	{
		low++;
	}
	swap1(arr, low, high);
}
//返回枢轴的位置。。。重要
return low;

}

//让n个元素 依此减少 减少到1个元素的时候,因为1个元素可以看成一个有序的序列

void QSort2(int *arr, int low, int high)
{
if( low < high )
{
int pivot = partition(arr, low, high);

	//对子序列1排序
	QSort2(arr, low, pivot-1);
	//对子序列2排序
	QSort2(arr, pivot+1, high);
}

}

void QSort(int *arr, int low, int high)
{
if( low < high )
{
int pivot = partition(arr, low, high);

	//对子序列1排序
	QSort2(arr, low, pivot-1);
	//对子序列2排序
	QSort2(arr, pivot+1, high);
}

}

void QuickSort(int arr, int len) // O(nlogn)
{
QSort(arr, 0, len-1);
}

void PercDown(int *arr, int i, int N)
{
int child;
ElementType Tmp;

for (Tmp = arr[i]; 2*i+1 < N; i = child){
    child = 2*i+1; //注意数组下标是从0开始的,所以左孩子的求发不是2*i
    if (child != N - 1 && arr[child + 1] > arr[child])
        ++child;                //找到最大的儿子节点
    if (Tmp < arr[child])
        arr[i] = arr[child];
    else
        break;
}
arr[i] = Tmp;

}

void HeapSort(int *arr, int N)
{
int i;
for (i = N / 2; i >= 0; --i)
PercDown(arr, i, N); //构造堆
for(i=N-1;i>0;–i)
{
swap1(arr,0,i); //将最大元素(根)与数组末尾元素交换,从而删除最大元素,重新构造堆
PercDown(arr, 0, i);
}
}

void radixSort(int *arr, int len)
{
int i;
void innerCountingSort(int *arr, int len, int d);//内部的计数排序声明
for (i = 0; i < WIDTH; i++)
{
innerCountingSort(arr, len, i);//对于每个元素的每一位都调用一次内部计数排序
}
}

void innerCountingSort(int *arr, int len, int d) //根据第d位数对数组进行排序
{
int i, j,k[MAXK] = {0};//数组K用来统计某一个元素的个数,该元素是待排序数组中某一位的数值
int *ip = (int *)malloc(len * sizeof(int));//用来存储待排序数组的元素的某一位的数值
int *bp = (int *)malloc(len * sizeof(int));
int getDValue(int value, int d);//获取待排序数组元素的第d位的数值
for (i = 0; i < len; i++)
{
ip[i] = getDValue(arr[i], d);
k[ip[i]]++;
}

for (j = 1; j < MAXK; j++) //统计小于等于j的元素个数
{
	k[j] = k[j] + k[j-1];
}

for (i = len - 1; i >= 0; i--)//按照第d位的大小,将数组元素放置到正确的位置
{
	bp[k[ip[i]] - 1] = arr[i];
	k[ip[i]]--;
}

for (i = 0; i < len; i++) //将按某一位排过序后的数组复制给原数组
{
	arr[i] = bp[i];
}

free(ip);
free(bp);

}

int getDValue(int value, int d) //获取一个数第d位数的值,位数索引从0开始
{
for (;d > 0 && value > 0; d–)
{
value = value / MAXK;
}
return value % MAXK;
}

int main()
{
int *arr=(int *)malloc(sizeof(int)*M);
SetFigure(arr, M); //写入随机数,并存入文件中

GetFigure(arr, M);
clock_t beg = clock();
Bubbling(arr, M);//冒泡排序
clock_t end = clock();
printf(“冒泡排序所需时间为:%.2lfms\n”, (end - beg) * 1000.0 / CLOCKS_PER_SEC);
//Print(arr,M);

memset(arr, 0, sizeof(int)*M); //初始化数组
GetFigure(arr, M);
clock_t beg1 = clock();
SelectionSort(arr,M);//选择排序
clock_t end1 = clock();
printf(“选择排序所需时间为:%.2lfms\n”, (end1 - beg1) * 1000.0 / CLOCKS_PER_SEC);
//Print(arr,M);

memset(arr, 0, sizeof(int)*M); //初始化数组
GetFigure(arr, M);
clock_t beg2 = clock();
InertionSort(arr,M);//插入排序
clock_t end2 = clock();
printf(“直接插入排序所需时间为:%.2lfms\n”, (end2 - beg2) * 1000.0 / CLOCKS_PER_SEC);
//Print(arr,M);

memset(arr, 0, sizeof(int)*M); //初始化数组
GetFigure(arr, M);
clock_t beg3 = clock();
ShellSort(arr, M);//希尔排序
clock_t end3 = clock();
printf(“希尔排序所需时间为:%.2lfms\n”, (end3 - beg3) * 1000.0 / CLOCKS_PER_SEC);
//Print(arr,M);

memset(arr, 0, sizeof(int)*M); //初始化数组
GetFigure(arr, M);
clock_t beg4 = clock();
QuickSort(arr, M);//快速排序
clock_t end4 = clock();
printf(“快速排序所需时间为:%.2lfms\n”, (end4 - beg4) * 1000.0 / CLOCKS_PER_SEC);
//Print(arr,M);

memset(arr, 0, sizeof(int)*M); //初始化数组
GetFigure(arr, M);
clock_t beg5 = clock();
HeapSort(arr, M);//堆排序
clock_t end5 = clock();
printf(“堆排序所需时间为:%.2lfms\n”, (end5 - beg5) * 1000.0 / CLOCKS_PER_SEC);
//Print(arr,M);

memset(arr, 0, sizeof(int)*M); //初始化数组
GetFigure(arr, M);
clock_t beg6 = clock();
radixSort(arr, M);//基数排序
clock_t end6 = clock();
printf(“基数排序所需时间为:%.2lfms\n”, (end6 - beg6) * 1000.0 / CLOCKS_PER_SEC);
//Print(arr,M);
return 0;
}

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱编程的小黑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值