排序算法的实现(C语言)

#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(&copy))
                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(&copy))
            {
                in(&list);
                copy_to_anothor(&copy, 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;
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值