【排序算法】冒泡排序(C语言)

这篇具有很好参考价值的文章主要介绍了【排序算法】冒泡排序(C语言)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【排序算法】—— 冒泡排序

一、冒泡排序的原理

​ 冒泡排序法:(Bubble sort)是一种基础的交换排序,非常简单,一学就懂

​ 对数组进行遍历,每次对相邻两个进行比较大小,若大的数值在前面则交换位置(升序),完成一趟遍历后数组中最大的数值到了数组的末尾位置,再对前面n-1个数值进行相同的遍历,一共完成n-1次遍历就实现了排序完成

  1. 第一趟对0~n-1遍历,依次对比前后的大小,若是不满足前小后大就交换,此时最大的数就被挪到了最后一个位置

冒泡排序,# 查找排序算法,c语言,排序算法,算法

  1. 0~n-2遍历,继续比较前后大小,此时前n-2个数中最大的数就到了倒数第二个位置

冒泡排序,# 查找排序算法,c语言,排序算法,算法

  1. 重复上述动作继续遍历,每一次都将最大的数向后挤,直到遍历完毕排序成功

冒泡排序,# 查找排序算法,c语言,排序算法,算法

二、代码实现

​ int类型数组的升序排序的简单实现

void bubble_sort(int* arr, int length)
{
    int i = 0;
    for (i=0; i<length-1; i++)			//遍历n-1次
    {
        int j = 0;
        for (j=0; j<length-1-i; j++)	//相邻两个数据依次进行比较
        {
            if (arr[j] > arr[j+1])		//顺序不对的交换位置
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

三、代码的优化

如果一次遍历,没有数据进行交换,则证明数组已经排好了顺序,不需要继续遍历,则引入flag变量标志记录第一次遍历是否有数据交换

void bubble_sort(int* arr, int length)
{
    int i = 0;
    for (i=0; i<length-1; i++)
    {
        int flag = 0;				   //flag标识
        int j = 0;
        for (j=0; j<length-1-i; j++)
        {
            if (arr[j] > arr[j+1])
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                flag = 1;				//发生数据交换,置flag为1
            }
        }
        if (flag == 0)					//若flag为0,则没有发生交换,跳出循环
        {
            break;
        }
    }
}

四、冒泡排序的效率

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)

  • 空间复杂度: O ( 1 ) O(1) O(1)

冒泡排序是稳定的排序算法(相同数据排序时不会影响原来的顺序,对结构体类型有影响)

五、模仿库函数的qsort实现

​ C语言中库函数qsort是通过函数指针cmp传入数据类型的比较方式,实现对各种数据类型都能进行排序的功能

​ 我们将模仿qsort函数使用冒泡排序算法实现对各种数据类型都能进行排序的函数,并且使用const关键字严格限制参的属性,达到很高的健壮性要求

1. 相关接口

  1. 冒泡排序函数
void bubble_sort(const void* base, const int length, const int size, int (*cmp)(void* e1, void* e2));
  • 参数:
    1. base:被排序的数组,由void*类型指针接收,const不能改变指针指向的内容,但可以改变指针的指向
    2. length:数组的长度,就是值的数量,由const限制不能改变大小
    3. size:数组中存放的数值类型的字节大小,就是一个值占几个字节的空间,由const限制不能改变大小
    4. cmp:数组中数据的比较规则,由cmp函数指针接收
  1. 交换数据函数

​ 将指针转换成char*,依次按照字节进行交换

void Swap(const void* e1, const void* e2, const int size);
  • 参数:
    1. e1:被交换的数据的地址,由void*指针接收,由const限制不能改变指针指向,但可以改变指针指向的内容
    2. e2:被交换的数据的地址,由void*指针接收,由const限制不能改变指针指向,但可以改变指针指向的内容
    3. size:被交换数据类型的字节大小,由const限制不能改变大小
  1. 比较函数:数组中数值的比较规则
int cmp(const void* e1, const void* e2);
  • 返回值:大于0,e1大;等于0,一样大;小于0,e2大
  • 参数:
    1. e1:被比较的数据的地址,由void*指针接收,由const限制不能改变指针指向,但可以改变指针指向的内容
    2. e1:被比较的数据的地址,由void*指针接收,由const限制不能改变指针指向,但可以改变指针指向的内容
  • 函数体:
    • 由用户自定义实现数值的比较规则

传参:

  1. 被比较数值的地址由void*指针接收

  2. 数值在数组中第 i 个位置:将void*转换成char指针,(char*)base + i*size

一些比较规则的演示文章来源地址https://www.toymoban.com/news/detail-735645.html

//int类型数据比较(升序)
int cmp(const void* e1, const void* e2)
{
    return *(int*)e1 - *(int*)e2;
}

//int类型数据比较(降序)
int cmp(const void* e1, const void* e2)
{
    return *(int*)e2 - *(int*)e1;	//降序就是把e1,e2的位置交换一下
}

//字符串比较(按字母升序)
#include <string.h>
int cmp(const void* e1, const void* e2)
{
    return strcmp((char*)e1, (char*)e2);	//其实有点多余,直接把strcmp传入bubble_sort中就行了
}

2. 代码实现

  1. 冒泡排序法的实现
#include <assert.h>		//引入头文件<assert.h>,使用assert函数断言

//交换数据
void Swap(const void* e1, const void* e2, const int size)
{
    assert(e1!=NULL && e1!=NULL && size>0);		//断言判断各个参数的合法性
    
    int i = 0;
    for (i=0; i<size; i++)
    {
        char temp = *((char*)e1 + i);
        *((char*)e1 + i) = *((char*)e2 + i);
        *((char*)e2 + i) = temp;
    }
}

//冒泡排序法
void bubble_sort(const void* base, const int length, const int size, int (*cmp)(const void* e1, const void* e2))
{
    assert(base!=NULL && length>0 && size>0 && cmp!=NULL);		//断言判断各个参数的合法性
    
    int i = 0;
    for (i=0; i<length-1; i++)
    {
        int flag = 0;
        int j = 0;
        for (j=0; j<length-1-i; j++)
        {
            if (cmp((char*)base + j*size, (char*)base + (j+1)*size) < 0)	//比较数据大小
            {
                Swap((char*)base + j*size, (char*)base + (j+1)*size, size);		//交换数值
                flag = 1;
            }
        }
        if (flag == 0)
        {
            break;
        }
    }
}
  1. 字符串数组升序排序的演示
#include <stdio.h>
#include <string.h>
int test1(void)
{
    char* strs[] = {"abc", "def", "bpm", "jqx"};
    bubble_sort(strs, sizeof(strs), sizeof(char*), strcmp);
    //printf打印排序之后的内容
}
  1. 整型数组降序排序的演示
#include <stdio.h>

//整型降序比较函数
int cmp_int(void* e1, void* e2)
{
    return *((int*)e2) - *((int*)e1);
}

//测试函数,用于调用排序函数
int test2(void)
{
    int nums[] = {2, 5, 8, 7, 1, 6};
    bubble_sort(strs, sizeof(nums), sizeof(int), cmp_int);
    //printf打印排序之后的内容
}

到了这里,关于【排序算法】冒泡排序(C语言)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【排序算法】C语言实现选择排序与冒泡排序

    这里是阿辉算法与数据结构专栏的第一篇文章,咱们就从排序算法开始讲起,排序算法有很多大致分为两类:基于比较的排序和非比较的排序 基于比较的排序:冒泡、选择、插入、希尔、堆、归并、随机快排 非比较的排序:桶排序 以上的排序算法阿辉都会讲到,今天阿辉主

    2024年02月04日
    浏览(31)
  • C语言算法——实现冒泡排序

    默认数组中的第一个数是原本数组中排好序的第一个数,然后每次将排好序的数组的后面的第一个数作为哨兵。每次哨兵都和前面的排好序的数组中的数从后往前进行比较,然后将哨兵插入到已经排好序的数组中。然后哨兵逐渐往后移动,逐步将哨兵插入到数组中,这就是

    2024年02月04日
    浏览(38)
  • 【C语言】解析C语言实现排序的算法(冒泡排序、插入排序、选择排序、快速排序、归并排序)

    本博客主要围绕五种常见的排序算法展开讨论,包括选择排序、快速排序、归并排序、冒泡排序和插入排序。针对每种算法,我对其思想、特点、时间复杂度、稳定性以及优缺点进行了详细解释和比较。 冒泡排序算法是一种简单且常用的排序算法。它通过重复地交换相邻的元

    2024年02月13日
    浏览(32)
  • Go 语言实现冒泡排序算法的简单示例

    以下是使用 Go 语言实现冒泡排序算法的简单示例: 在这个例子中, bubbleSort 函数接收一个整数切片,对切片中的元素进行冒泡排序。在 main 函数中,我们定义了一个示例数组,调用 bubbleSort 函数对其进行排序,并输出结果。 注意,冒泡排序算法的时间复杂度为 O(n^2),因此对

    2024年01月23日
    浏览(35)
  • 快速了解四种排序算法:希尔排序,堆排序,快速排序,冒泡排序(c语言)

     一个程序员一生中可能会邂逅各种各样的算法,但总有那么几种,是作为一个程序员一定会遇见且大概率需要掌握的算法。 1.1算法(algorithm ) 是指令的集合,是为解决特定问题而规定的一系列操作。 它是明确定义的可计算过程,以一个数据集合作为输入,并产生一个数据

    2024年02月16日
    浏览(42)
  • C语言入门:冒泡法排序、交换法排序和选择法排序算法的详解(代码分析)

     冒泡法排序 :顾名思义,小的数据就好像水中的气泡一样总是逐渐往上升, 大的数据就像石块一样往下沉,因此称为冒泡法排序法。 假如有n个数字,则需要进行n-1轮  第一轮结果:最大的数,被放在了最后一位  第二轮:元素 ‘8’ 已经拍好了顺序,所以只用将前4个元素

    2024年02月03日
    浏览(36)
  • C语言实现八大排序算法(详解插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序(递归和非递归)、归并排序(递归和非递归)和计数排序)

    本篇文章使用C语言实现了数据结构中常见的八大排序算法,它们分别是 插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序和计数排序 。在排序算法的实现过程中,每种算法都有其独特的特点和适用场景。插入排序通过逐步构建有序序列来排序,希尔

    2024年01月24日
    浏览(38)
  • Java---第四章(数组基础,冒泡排序,二分查找,多维数组)

    概念: 数组是编程语言中的一种常见的数据结构,能够存储一组相同类型的数据 作用: 存储一组相同类型的数据,方便进行数理统计(求最大值,最小值,平均值以及总和),也可以进行信息的展示 定义: 第一种: 只能在定义数组同时赋值时使用 第二种: 可以在定义数组

    2024年02月09日
    浏览(38)
  • 【数据结构与算法】排序算法:冒泡排序,冒泡排序优化,选择排序、选择排序优化

    目录 一、冒泡排序 1、冒泡排序思想 2、冒泡排序算法的性能分析 代码实现: 二、选择排序 1、选择排序思想 2、选择排序算法的性能分析  代码实现: 1、冒泡排序思想 冒泡排序的基本思想是通过相邻元素之间的比较和交换来逐步将最大(或最小)的元素移到右边(或左边

    2024年01月19日
    浏览(38)
  • C++常见排序算法——冒泡排序算法

    首先说一下冒泡排序的基本算法思想: 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。 这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸

    2023年04月08日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包