C语言实现经典排序算法的示例代码

 更新时间:2022年8月8日 22:11  点击:351 作者:随便写写。

一、冒泡排序

1.原理

从数组的头开始不断比较相邻两个数的大小,不断将较大的数右移,一个循环后,最大数移至最后一位,无序数组规模减一。不断重复前面动作,知道数组完全有序。

2.实现

void swap(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
void bubble_sort(int* arr, int len)
{
    bool issort = false;
    while (!issort)
    {
        issort = true;//如果有序则直接退出
        for (int i = 1; i < len; i++)
        {
            if (arr[i-1] > arr[i])//不断比较相邻两个数
            {
                swap(&arr[i - 1], &arr[i]);//将较大的数不断往右移
                issort = false;//如果进行了交换则无序
            }
        }
        len--;//无序规模减一
    }
}

3.算法分析

时间复杂度: 最好情况,当数组完全有序,则只需要进行一轮比较,时间复杂度为o(n);最坏情况为完全无序,每次比较后都要将该数移至数组末尾,时间复杂度为o(n ^2);平均时间复杂度为o(n ^2)。

空间复杂度: 冒泡排序为就地排序,空间复杂度为o(1)。

稳定排序: 当数字相同时不会改变相对次序。

二、选择排序

1.原理

数组前面为无序,后面为有序。刚开始全是无序,从中选择一个最大值与最后一个无序数字进行交换,无序数组规模减一,有序数组规模加一。不断循环前面操作,直到数组变为有序数组。或者前面为有序数组,后面为无序数组,不断选择最小值与无序数组的第一个数交换,前面的有序数组加一,后面的无序数组减一。

2.实现

void selection_sort(int* arr, int len)
{
    int max_index;
    while (len)
    {
        max_index = 0;
        for (int i = 1; i < len; i++)
        {
            if (arr[max_index] < arr[i])
            {
                max_index = i;//获取最大值的索引
            }
        }
        swap(&arr[max_index], &arr[len - 1]);//将最大值与最后一个值交换
        len--;//无序规模减一
    }
}

3.算法分析

时间复杂度: 所有的复杂度为每次选择最大值,不管数字的有序性,时间复杂度都为o(n)+o(n-1)+…+o(1)=o(n^2)。所以该算法平均复杂度、最好情况、最差情况都为o(n ^2)。

空间复杂度: 就地排序,空间复杂度为o(1)。

不稳定性算法: 排序后相同元素的顺序可能被打乱。例子:选择最大进行排序。3,1,2,2* 第一轮排序后 2*,1,2,3 2的相对顺序发生了改变。选择最小进行排序,2*,2,3,1 第一轮排序后1,2,3,2*. 2的相对顺序也被打乱。如果增加空间复杂度也能将选择排序变成稳定性排序。

三、插入排序

1.原理

数组前面为有序,后面为无序,将无序数组中的第一个数不断插入有序数组中(具体实现为不断比较相邻两数大小,前面一个数大于后一个数,则交换顺序,较小的数不断前移),有序规模增加一,无序规模减小一。或者,数组前面为无序,后面为有序,通过将无序数组的最后一位数字插入有序数组中(具体实现为将无序数组的最后一位与相邻的有序数组不断比较,将无序数组不断右移)。

2.实现

void insert_sort(int arr[], int len)
{
    for (int i = 1; i < len; i++)//i前面为有序
    {
        for (int j = i - 1; j >= 0; j--)//j为有序数的末尾
        {
            bool issort = true;//当数组有序时能够提前退出
            if (arr[j] > arr[j + 1])//将无序数组的第一个数不断与有序数组比较
            {
                swap(&arr[j], &arr[j + 1]);//将无序数字插入有序数组合适的位置
                issort = false;
            }
            if (issort) break;
        }
    }
}

3.算法分析

时间复杂度: 插入排序和冒泡排序类似,最好情况完全有序则时间复杂度为o(n),最坏情况为完全无序时间复杂度为o(n^2),平均复杂度为o(n ^2)。

空间复杂度: 就地排序不需要额外空间,空间复杂度为o(1)。

稳定性排序: 和冒泡排序类似。

四、希尔排序

1.原理

每次选择一个增量进行分组,增量不断减小到一(为插入排序),数组不断变得有序,增量为一时变成完全有序。属于插入排序的改进,通过增量进行分组,对每一组进行插入排序,相比于插入排序的优势在于,shell排序能够大尺度的移动每一组的最小值,而插入排序得挨着进行比较,所以shell排序效率更高。

增量为6:

每一组只有两个数,分别比较两个数的大小,如64,57交换顺序变成57,64,所有的分组比较完后继续缩减增量。

增量为3:

每一组有四个数,总共三组,分别为23,12,53,79;57,9,64,87;24,16,71,97;以增量开始(12开始)遍历数组,遍历到12则在第一组中对12进行插入排序,交换23和12的顺序;遍历到9则在第二组对9进行插入排序。。。。遍历到64对一组中的9,57,64进行插入排序。最后每一组都变得有序。整体有序性变大。

增量为1:

对之前排序过的数组进行插入排序,通过前面的步骤数组有序性变大,最后进行插入排序的效率就更高。

2.实现

void shell_sort(int* arr, int len)
{
    int gap = 0; //分组的跨度
    int i = 0;
    int j = 0;
    for (gap = len / 2; gap >= 1; gap /= 2) //分组增量
    {
        for (i = gap; i < len; i++) {  //遍历每组
            for (j = i - gap; j >= 0; j -= gap)  //对组内进行插入排序
            {
                if (arr[j] > arr[j + gap])
                {
                    swap(&arr[j], &arr[j + gap]);
                }
            }
        }
    }
}

3.算法分析

时间复杂度:最好情况为完全有序o(n),最差情况为完全无序o(n^2),平均复杂度为o(n ^1.3)。

空间复杂度:该算法为就地排序空间复杂度为o(1)。

稳定性:shell排序在分组中可能将相同数字划分成不同的分组,会改变相对顺序,属于不稳定性排序算法。

总结

冒泡排序、选择排序、插入排序、希尔排序的实现都是基于线性表进行实现的(数组或者链表),实现逻辑都是通过比较数字的大小。算法的时间复杂度都比较大,但是属于就地排序,不需要额外空间。几种算法相比之下希尔排序更具有优势。

到此这篇关于C语言实现经典排序算法的示例代码的文章就介绍到这了,更多相关C语言排序算法内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://blog.csdn.net/qq_36472340/article/details/126166899

[!--infotagslink--]

相关文章

  • C语言实现放烟花的程序

    这篇文章主要为大家详细介绍了C语言实现放烟花的程序,有音乐播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-23
  • C语言中的字符(char)详细讲解

    本篇文章主要介绍C语言中char的知识,并附有代码实例,以便大家在学习的时候更好的理解,有需要的可以看一下...2020-04-25
  • C#几种排序算法

    作者:Sabine 【导读】本文介绍了C#的四种排序算法:冒泡排序、选择排序、插入排序和希尔排序  冒泡排序 using System; namespace BubbleSorter { public class Bubb...2020-06-25
  • 经典实例讲解C#递归算法

    这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
  • 详解如何将c语言文件打包成exe可执行程序

    这篇文章主要介绍了详解如何将c语言文件打包成exe可执行程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-25
  • antdesign-vue结合sortablejs实现两个table相互拖拽排序功能

    这篇文章主要介绍了antdesign-vue结合sortablejs实现两个table相互拖拽排序功能,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-09
  • C# 参数按照ASCII码从小到大排序(字典序)

    这篇文章主要介绍了C# 参数按照ASCII码从小到大排序(字典序)的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C语言中free函数的使用详解

    free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
  • C语言中计算正弦的相关函数总结

    这篇文章主要介绍了C语言中计算正弦的相关函数总结,包括正弦和双曲线正弦以及反正弦的函数,需要的朋友可以参考下...2020-04-25
  • 详解C语言中的rename()函数和remove()函数的使用方法

    这篇文章主要介绍了详解C语言中的rename()函数和remove()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
  • js实现列表按字母排序

    这篇文章主要为大家详细介绍了js实现列表按字母排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-11
  • C语言中求和、计算平均值、方差和标准差的实例

    这篇文章主要介绍了C语言中求和、计算平均值、方差和标准差的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-10
  • C语言的基本语法详解

    本篇文章主要讲解C语言 基本语法,这里提供简单的示例和代码来详细讲解C语言的基本语法,开始学习C语言的朋友可以看一下,希望能够给你带来帮助...2021-09-18
  • C#实现排序的代码详解

    在本篇文章里小编给大家整理的是关于C#实现排序的代码以及相关知识点,需要的朋友们参考下。...2020-06-25
  • C#中实现任意List的全组合算法代码

    这篇文章主要是介绍了.net C# 实现任意List的全组合算法实现代码,需要的朋友可以参考下...2020-06-25
  • 同时兼容JS和C#的RSA加密解密算法详解(对web提交的数据加密传输)

    这篇文章主要给大家介绍了关于同时兼容JS和C#的RSA加密解密算法,通过该算法可以对web提交的数据进行加密传输,文中通过图文及示例代码介绍的非常详细,需要的朋友们可以参考借鉴,下面来一起看看吧。...2020-06-25
  • C语言中send()函数和sendto()函数的使用方法

    这篇文章主要介绍了C语言中send()函数和sendto()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
  • js实现数组冒泡排序、快速排序原理

    这篇文章主要为大家详细介绍了js实现数组冒泡排序、快速排序的原理,感兴趣的小伙伴们可以参考一下...2016-03-10
  • 图文详解Heap Sort堆排序算法及JavaScript的代码实现

    这篇文章以图文详解Heap Sort堆排序算法及JavaScript的代码实现,堆排序算法基于类二叉树的堆数据结构,需要的朋友可以参考下...2016-05-05
  • C语言实现从文件读入一个3*3数组,并计算每行的平均值

    今天小编就为大家分享一篇C语言实现从文件读入一个3*3数组,并计算每行的平均值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25