#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <windows.h>
// #include <vector>
// #include <iostream>
// using namespace std;
const int MAX_SIZE = 1e7;
typedef struct seqlist
{
int *data;
int length;
int size;
} seqlist;
void COLOR_PRINT(const int a, int color)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color);
printf("%04d ", a);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | 15);
}
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
bool ini(seqlist *L)
{
L->data = (int *)malloc(MAX_SIZE * sizeof(int));
if (L->data != NULL)
{
L->length = 0;
L->size = MAX_SIZE;
return 1;
}
else
{
printf("ERROR!\n");
return 0;
}
}
int in(seqlist *L)
{
int n;
printf("请输入你想排列的关键字(整形)长度\n");
scanf("%d", &n);
printf("请输入你想排列的关键字(整形)序列\n");
while (L->length < n)
{
int da;
scanf("%d", &da);
L->data[L->length++] = da;
}
return 0;
}
void insertsort(seqlist *L)
{
clock_t starttime = clock();
int i, k, j, temp;
for (i = 1; i < L->length; i++)
{
temp = L->data[i];
for (j = i - 1; j >= 0 && L->data[j] > temp; j--) //将有序序列中比待插入关键字小的关键字全部后移一位
{
L->data[j + 1] = L->data[j];
}
L->data[j + 1] = temp; //待插入关键字插入
for (k = 0; k < L->length; k++) //输出每趟结果
{
printf("%04d ", L->data[k]);
if (k == i)
printf("\b|");
}
printf("\n");
}
clock_t endtime = clock();
printf("排序用时:%lfs\n", (double)(endtime - starttime) / CLOCKS_PER_SEC);
}
void insertsort_of_BS(seqlist *L)
{
clock_t starttime = clock();
//此处二分查找使用循环实现,下方快排使用递归实现
int i, k, j, temp, l, r, mid;
for (i = 1; i < L->length; i++)
{
temp = L->data[i];
//二分查找
l = 0;
r = i - 1;
while (l <= r) //截止条件
{
mid = (l + r) >> 1; //正整数除以二的最快写法
if (temp < L->data[mid])
r = mid - 1;
else
l = mid + 1;
}
for (j = i - 1; j > r; j--) //将有序序列中比待插入关键字小的关键字全部后移一位
L->data[j + 1] = L->data[j];
L->data[r + 1] = temp; //待插入关键字插入
for (k = 0; k < L->length; k++) //输出每趟结果
{
printf("%04d ", L->data[k]);
if (k == i)
printf("\b|");
}
printf("\n");
}
clock_t endtime = clock();
printf("排序用时:%lfs\n", (double)(endtime - starttime) / CLOCKS_PER_SEC);
}
void selectionsort(seqlist *L)
{
clock_t starttime = clock();
int mi, k, i, j;
for (i = 0; i < L->length - 1; i++)
{
mi = i; //找i后面的关键字中最小的
for (j = i + 1; j < L->length; j++)
{
if (L->data[j] < L->data[mi])
mi = j;
}
swap(L->data[i], L->data[mi]);
for (k = 0; k < L->length; k++) //输出每趟结果
{
printf("%04d ", L->data[k]);
if (k == i)
printf("\b|");
}
printf("\n");
}
clock_t endtime = clock();
printf("排序用时:%lfs\n", (double)(endtime - starttime) / CLOCKS_PER_SEC);
}
void bubblesort(seqlist *L)
{
clock_t starttime = clock();
int i, j, k, q, flag;
for (i = 0; i < L->length - 1; i++)
{
flag = 0;
for (j = 0; j < L->length - i - 1; j++)
{
if (L->data[j] > L->data[j + 1])
{
++flag;
swap(L->data[j], L->data[j + 1]);
}
}
for (k = 0; k < L->length; k++) //输出每趟结果
{
printf("%04d ", L->data[k]);
if (k == L->length - i - 2)
printf("\b|");
}
printf("\n");
if (flag <= 1) //这里零次交换或只有一次交换我就提前结束,比传统冒泡快n
break;
}
clock_t endtime = clock();
printf("排序用时:%lfs\n", (double)(endtime - starttime) / CLOCKS_PER_SEC);
}
void shellsort(seqlist *L)
{
clock_t starttime = clock();
int i, j, k, temp, q, n = L->length;
int gap = n / 2; //增量
while (gap >= 1)
{
//插入排序
for (i = 0; i < gap; i++)
{
for (j = i + gap; j < n; j += gap)
{
temp = L->data[j];
for (q = j - gap; q >= 0 && L->data[q] > temp; q -= gap)
L->data[q + gap] = L->data[q];
L->data[q + gap] = temp;
}
for (k = 0; k < L->length; k++) //输出每趟结果
{
printf("%04d ", L->data[k]);
if ((k + 1) % gap == 0)
printf("\b|");
}
printf("\n");
}
gap /= 2;
}
clock_t endtime = clock();
printf("排序用时:%lfs\n", (double)(endtime - starttime) / CLOCKS_PER_SEC);
}
clock_t quicksort(seqlist *L, int left, int right)
{
//此处递归实现
int l, r, k, z, mark;
if (left > right)
return clock();
l = left;
r = right;
int benchmark = L->data[left]; //以区间的最左为基准
while (l < r)
{ //取最左端元素为基准
while (l < r && L->data[r] >= benchmark) //找到右边第一个比基准值小的元素
r--;
L->data[l] = L->data[r]; //移动
while (l < r && L->data[l] <= benchmark) //找到左边第一个比基准值大的元素
l++;
L->data[r] = L->data[l]; //移动
}
L->data[l] = benchmark;
for (k = 0; k < L->length; k++) //输出当前结果
{
if (k == l)
COLOR_PRINT(L->data[k], 12);
else
printf("%04d ", L->data[k]);
}
printf("\n");
quicksort(L, left, l - 1);
quicksort(L, l + 1, right);
}
void out(seqlist L)
{
for (int i = 0; i < L.length; i++)
{
printf("%04d", L.data[i]);
if ((i + 1) % 10 == 0)
printf("\n");
else
printf(" ");
}
getchar();
getchar();
}
void copy_to_anothor(seqlist *A, seqlist B)
{
for (int i = 0; i < B.length; i++)
A->data[i] = B.data[i];
}
void menu()
{
printf("请选择功能:\n");
printf("0.生成随机数列并输入新创建的顺序表\n");
printf("1.创建新的顺序表\n");
printf("2.直接插入排序\n");
printf("3.二分优化的插入排序\n");
printf("4.选择排序\n");
printf("5.冒泡排序\n");
printf("6.希尔排序\n");
printf("7.快排\n");
printf("8.还原关键字顺序\n");
printf("9.显示当前关键字\n");
printf("10.退出\n");
}
int main()
{
seqlist list;
seqlist copy;
while (1)
{
system("cls");
menu();
int x;
scanf("%d", &x);
switch (x)
{
case 0: //生成随机数
printf("输入数列长度\n");
int n;
scanf("%d", &n);
if (ini(&list) && ini(©))
srand((int)time(NULL));
for (int i = 0; i < n; i++)
{
list.data[list.length++] = rand() % 10000; //输入顺序表
copy.data[copy.length++] = list.data[i]; //拷贝
printf("%04d", list.data[i]); //显示该随机数
if ((i + 1) % 10 == 0)
printf("\n");
else
printf(" ");
}
getchar();
getchar();
break;
case 1: //读入关键字
if (ini(&list) && ini(©))
{
in(&list);
copy_to_anothor(©, list);
}
getchar();
break;
case 2: //插入
out(list);
insertsort(&list);
out(list);
break;
case 3: //二分优化的插入
out(list);
insertsort_of_BS(&list);
out(list);
break;
case 4: //选择
out(list);
selectionsort(&list);
out(list);
break;
case 5: //冒泡
out(list);
bubblesort(&list);
out(list);
break;
case 6: //希尔
shellsort(&list);
out(list);
break;
case 7: //快排
{
out(list);
clock_t starttime = clock();
clock_t endtime = quicksort(&list, 0, list.length - 1);
printf("排序用时:%lfs\n", (double)(endtime - starttime) / CLOCKS_PER_SEC);
out(list);
break;
}
case 8:
copy_to_anothor(&list, copy);
break;
case 9:
out(list);
break;
case 10:
return 0;
}
}
}
排序算法的实现(C语言)
最新推荐文章于 2022-08-08 14:18:45 发布