#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <math.h>
//选择排序
long selectSort(int* arr, int length)
{
struct timeval time1, time2;
gettimeofday(&time1, NULL);
for (int i = 0; i < length - 1; i++)
{
for (int j = i + 1; j < length; j++)
{
if (arr[i] > arr[j])
{
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
}
}
gettimeofday(&time2, NULL);
return time2.tv_sec - time1.tv_sec;
}
//插入排序
long insertSort(int* arr, int length)
{
struct timeval time1, time2;
gettimeofday(&time1, NULL);
for (int i = 1; i < length; i++)
{
if (arr[i] < arr[i - 1])
{
for (int j = 0; j < i; j++)
{
if (arr[i] < arr[j])
{
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
}
}
}
gettimeofday(&time2, NULL);
return time2.tv_sec - time1.tv_sec;
}
//折半插入排序
long binaryInsertSort(int* arr, int length)
{
struct timeval time1, time2;
gettimeofday(&time1, NULL);
int head, tail, mid;
for (int i = 1; i < length; i++)
{
if (arr[i] < arr[i - 1])
{
head = 0;
tail = i - 1;
while (head <= tail)
{
mid = (head + tail) / 2;
if (arr[i] < arr[mid])
{
tail = mid - 1;
continue;
}
if (arr[i] > arr[mid])
{
head = mid + 1;
}
if (arr[i] == arr[mid])
{
head = mid;
break;
}
}
for (int k = i; k > head; k--)
{
arr[k] = arr[k] ^ arr[k - 1];
arr[k - 1] = arr[k] ^ arr[k - 1];
arr[k] = arr[k] ^ arr[k - 1];
}
}
}
gettimeofday(&time2, NULL);
return time2.tv_sec - time1.tv_sec;
}
//希尔排序内部替换
void shellReplace(int* arr, int length, int interval)
{
int i = 0, j;
while (i + interval <= length - 1)
{
if (arr[i] > arr[i + interval])
{
arr[i] = arr[i] ^ arr[i + interval];
arr[i + interval] = arr[i] ^ arr[i + interval];
arr[i] = arr[i] ^ arr[i + interval];
j = i;
while (j - interval >= 0)
{
if (arr[j] < arr[j - interval])
{
arr[j] = arr[j] ^ arr[j - interval];
arr[j - interval] = arr[j] ^ arr[j - interval];
arr[j] = arr[j] ^ arr[j - interval];
j -= interval;
}
else
{
break;
}
}
}
i++;
}
}
//希尔排序
long shellSort(int* arr, int length)
{
struct timeval time1, time2;
gettimeofday(&time1, NULL);
int interval = length >> 1;
while (interval > 0)
{
shellReplace(arr, length, interval);
interval >>= 1;
}
gettimeofday(&time2, NULL);
return time2.tv_sec - time1.tv_sec;
}
void quickSortDetail(int* arr, int start, int end)
{
if (start < end)
{
int left = start;
int right = end;
int store = arr[end];
while (left < right)
{
while (arr[left] <= store && left != right)
{
left++;
}
if (left != right)
{
arr[right] = arr[left];
}
while (arr[right] > store && left != right)
{
right--;
}
if (left != right)
{
arr[left] = arr[right];
}
}
arr[left] = store;
quickSortDetail(arr, start, left - 1);
quickSortDetail(arr, left + 1, end);
}
}
//快速排序
long quickSort(int* arr, int length)
{
struct timeval time1, time2;
gettimeofday(&time1, NULL);
quickSortDetail(arr, 0, length - 1);
gettimeofday(&time2, NULL);
return time2.tv_sec - time1.tv_sec;
}
//冒泡排序
long bubbleSort(int* arr, int length)
{
struct timeval time1, time2;
gettimeofday(&time1, NULL);
for (int i = length - 1; i > 0; i--)
{
for (int j = 0; j < i; j++)
{
if (arr[j] > arr[j + 1])
{
arr[j] = arr[j] ^ arr[j + 1];
arr[j + 1] = arr[j] ^ arr[j + 1];
arr[j] = arr[j] ^ arr[j + 1];
}
}
}
gettimeofday(&time2, NULL);
return time2.tv_sec - time1.tv_sec;
}
void buildHeap(int* arr, int end)
{
struct timeval time1, time2;
gettimeofday(&time1, NULL);
int nodeChild = end >> 1;
int* max;
for (int i = nodeChild - 1; i >= 0; i--)
{
if ((i << 1) + 2 >= end)
{
if (arr[(i << 1) + 1] > arr[i])
{
arr[i] = arr[i] ^ arr[(i << 1) + 1];
arr[(i << 1) + 1] = arr[i] ^ arr[(i << 1) + 1];
arr[i] = arr[i] ^ arr[(i << 1) + 1];
}
}
else
{
max = arr[(i << 1) + 1] > arr[(i << 1) + 2] ? &arr[(i << 1) + 1] : &arr[(i << 1) + 2];
if (*max > arr[i])
{
arr[i] = arr[i] ^ *max;
*max = arr[i] ^ *max;
arr[i] = arr[i] ^ *max;
}
}
}
}
//堆排序
long heapSort(int* arr, int length)
{
struct timeval time1, time2;
gettimeofday(&time1, NULL);
int i = length;
while (i > 1)
{
buildHeap(arr, i);
arr[0] = arr[0] ^ arr[i - 1];
arr[i - 1] = arr[0] ^ arr[i - 1];
arr[0] = arr[0] ^ arr[i - 1];
i--;
}
gettimeofday(&time2, NULL);
return time2.tv_sec - time1.tv_sec;
}
//归并排序(由于该算法比较复杂,将详细注释)
long mergerSort(int* arr, int length)
{
//定义时间结构体
struct timeval time1, time2;
//获取当前时间
gettimeofday(&time1, NULL);
//申请一块与待排序的数组相同大小的空间
int* copy = (int*)malloc(sizeof(int) * length);
//定义原数组和新建数组交换标识变量,默认从原数组开始
int isArr = 1;
//定义每一组的元素个数,之所以为double是为了下面的ceil函数做准备
double groupNum = 1;
//定义变量,i为循环变量,start为跟随数组索引变量,index为每一次数组复制时的位置记录变量,
// groupA是分组一的索引记录变量
//groupB为分组二的索引记录变量,groupBinary表示有几对分组进行归并
int i, start, index, groupA, groupB, groupBinary;
//groupCount计算出分组的数量
int groupCount = (int)ceil(length / groupNum);
//判断,当分组数量大于1时进行循环,为1时也自然就不用循环了,因为都已经排好序了
while (groupCount > 1)
{
//计算出分组对数
groupBinary = groupCount / 2;
//赋start为0
start = 0;
//赋index为0
index = 0;
//总共肯定只能进行groupBinary对分组的归并,分布上组的肯定也只有一个,放在下一次的比较中
for (i = 0; i < groupBinary; i ++)
{
//每一对分组归并,从数组的start位置开始
groupA = start;
//这一对分组中的第二组从start位置偏移groupNum个位置开始,因为每一对分组总是组里元素数量的两倍
groupB = start + (int)groupNum;
//循环对一对分组进行归并,原理是,那个小,那个先往待放入数组走
while (groupA < start + groupNum && groupB < start + 2 * groupNum && groupB < length)
{
//由于是两个数组交替赋值,所以isArr就是区分它们的
if (isArr == 1)
{
//如果第一组比后一组的元素小,则优先进入,因为是升序排列嘛
if (arr[groupA] < arr[groupB])
{
copy[index] = arr[groupA];
index ++;
groupA ++;
}
else
{
copy[index] = arr[groupB];
index ++;
groupB ++;
}
}
else
{
if (copy[groupA] < copy[groupB])
{
arr[index] = copy[groupA];
index ++;
groupA ++;
}
else
{
arr[index] = copy[groupB];
index ++;
groupB ++;
}
}
}
//当某一个分组没有元素以后,剩下的那个分组要是有元素,就依次把所有剩下的元素塞进去
while (groupA < start + groupNum)
{
if (isArr == 1)
{
copy[index] = arr[groupA];
index ++;
groupA ++;
}
else
{
arr[index] = copy[groupA];
index ++;
groupA ++;
}
}
while (groupB < start + 2 * groupNum && groupB < length)
{
if (isArr == 1)
{
copy[index] = arr[groupB];
index ++;
groupB ++;
}
else
{
arr[index] = copy[groupB];
index ++;
groupB ++;
}
}
start += 2 * groupNum;
}
if (isArr == 1)
{
//由于有没有参与归并的分组,所以就把这些被暂时遗弃的分组再移到当前活动数组
while (index < length)
{
copy[index] = arr[index];
index ++;
}
isArr = 0;
}
else
{
while (index < length)
{
arr[index] = copy[index];
index ++;
}
isArr = 1;
}
groupNum *= 2;
groupCount = (int)ceil(length / groupNum);
}
//如果排完序,这个活跃数组不恰好是arr,那么就是讲copy数组的值一个个的赋过去
if (isArr == 0)
{
for (i = 0; i < length; i++)
{
arr[i] = copy[i];
}
}
//回收备用数组copy,以免造成内存浪费
free(copy);
//获取排完序当前时间
gettimeofday(&time2, NULL);
//返回时间差
return time2.tv_sec - time1.tv_sec;
}
void printArr(int* arr, int length)
{
for (int i = 0; i < length; i++)
{
printf("%d \t", arr[i]);
}
printf("\n");
}
int main(int argc, char** argv)
{
srand(time(NULL));
int* arr = (int*)malloc(sizeof(int) * 50000);
for (int i = 0; i < 50000; i++)
{
arr[i] = rand();
}
printf("Select sort use time: %ld \n", selectSort(arr, 50000));
for (int i = 0; i < 50000; i++) {
arr[i] = rand();
}
printf("Insert sort use time: %ld \n", insertSort(arr, 50000));
for (int i = 0; i < 50000; i++) {
arr[i] = rand();
}
printf("Binary insert sort use time: %ld \n", binaryInsertSort(arr, 50000));
for (int i = 0; i < 50000; i++) {
arr[i] = rand();
}
printf("Shell sort use time: %ld \n", shellSort(arr, 50000));
for (int i = 0; i < 50000; i++) {
arr[i] = rand();
}
printf("Quick sort use time: %ld \n", quickSort(arr, 50000));
for (int i = 0; i < 50000; i++) {
arr[i] = rand();
}
printf("Bubble sort use time: %ld \n", bubbleSort(arr, 50000));
for (int i = 0; i < 50000; i++) {
arr[i] = rand();
}
printf("Heap sort use time: %ld \n", heapSort(arr, 50000));
for (int i = 0; i < 50000; i++) {
arr[i] = rand();
}
printf("Merger sort use time: %ld \n", mergerSort(arr, 50000));
free(arr);
return 0;
}
打开App,阅读手记