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

目录

  • 一、冒泡排序的原理
  • 二、代码实现
  • 三、代码的优化
  • 四、冒泡排序的效率
  • 五、模仿库函数的qsort实现
    • 1. 相关接口
    • 2. 代码实现

一、冒泡排序的原理

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

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

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

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

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

二、代码实现

​ 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(n2)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

一些比较规则的演示

//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语言)相关推荐

  1. C语言基础排序算法-冒泡排序

    C语言基础排序算法-冒泡排序 什么是冒泡排序? 顾名思义,这种排序方法就像水中的气泡一样,从底逐渐往上冒,一次前进一步.我们来看一个例子,看看到底是怎么冒泡的.假设有一个数组3,2,5,4,1,我们希 ...

  2. 十种经典排序算法精粹(c语言版本)

    下面给出这段时间我苦心研究验证过的十种经典排序算法的C语言版本,即下面的排序算法: 插入排序,shell排序,冒泡排序,快速排序,选择排序,堆排序,归并排序,桶排序,基数排序和计数排序.整理出来以作备 ...

  3. 常见排序算法(C语言实现)

    常见排序算法(C语言实现) 文章目录 常见排序算法(C语言实现) 一.插入排序 二.希尔排序 三.选择排序 四.堆排序 五.冒泡排序 六.快速排序 七.归并排序 一.插入排序 void insertS ...

  4. 数据结构-排序算法(c语言实现篇)

    数据结构-排序算法(c语言实现篇) 排序算法是非常常用的算法,从介绍排序的基本概念,到介绍各种排序算法的思想.实现方式以及效率分析.最后比较各种算法的优劣性和稳定性. 1 排序的概念及应用 1.1 排 ...

  5. 经典排序算法 - 冒泡排序Bubble sort

    经典排序算法 - 冒泡排序Bubble sort 其原理是比较接近的数字22,按照从小到交换大或降序排列, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头開始进行两两比較交换,直到倒 ...

  6. 排序算法——冒泡排序(Bubble Sort)

    排序算法--冒泡排序(Bubble Sort) 算法简介(Introduction) Bubble sort is to compare adjacent elements of the list a ...

  7. python排序算法 ——冒泡排序(附代码)

    python排序算法 --冒泡排序 文章目录 python排序算法 --冒泡排序 一.前言 二.算法描述 三.代码实现 总结 一.前言 相关知识来自<python算法设计与分析>.初级排序 ...

  8. 十大经典排序算法-冒泡排序算法详解

    十大经典排序算法 十大经典排序算法-冒泡排序算法详解 十大经典排序算法-选择排序算法详解 十大经典排序算法-插入排序算法详解 十大经典排序算法-希尔排序算法详解 十大经典排序算法-快速排序算法详解 十 ...

  9. 小白学六大排序算法(C语言版)

    今天在csdn刷blink的时候,刷到一个冒泡排序的吐槽,看了看评论区,发现不少人分不清选择排序和冒泡排序,笔者想了一下,发现这两个排序确实相似度蛮高的,所以总结了c语言里涉及到六个排序算法,笔者才疏 ...

  10. 排序算法---冒泡排序(java版)

    冒泡排序 原理 冒泡排序(Bubble Sort)是一种简单的排序算法,它通过依次比较两个相邻的的元素,看两个元素是否满足大小关系要求,如果不满足则交换两个元素.每一次冒泡会让至少一个元素移动到它应该 ...

最新文章

  1. 优词词根词典mdx_推荐|一波好用的在线英语词典网站
  2. android 稳定性测试工具,APP 稳定性测试工具-Fastbot_Android详解
  3. 北京2019高考分数线:本科理423文480
  4. 每一个项目都可以有一个项目blog page
  5. ubuntu下修改用户的默认目录
  6. postgresql 修改表字段_关于一些postgresql特有的概念以及安装方法的叙述
  7. 寒假作业3(传说中的写软件)
  8. [Noip2007]Core树网的核
  9. Vue CLI 3 中文文档
  10. Raki的读paper小记:How to Fine-Tune BERT for Text Classification?
  11. linux性能监控命令dstat详解【杭州多测师_王sir】【杭州多测师】
  12. 轻量级架构和重量级架构
  13. 2021 年 15 款适用于 PC 和 Mac 的最佳 Android 模拟器
  14. 教你如何使用语雀提高效率
  15. 不羁野草挑战遗传法则
  16. Python 中的取余与取整操作
  17. [Swift]代码触发UIButton的点击事件
  18. java join的用法
  19. jmeter 压测java代码
  20. Android OpenGL ES 画球体

热门文章

  1. war2 洛谷模拟赛day2 t3 状压
  2. asp.net使用Mysql乱码处理
  3. 第2章 系统的分层结构
  4. 用Excel 公式求 金额的差额
  5. 图像处理——alpha融合
  6. javaweb在线考试系统_有没有在线考试系统能承载几千人同时在线考试的?
  7. Pyqt之QApplication
  8. 【regresson下】L1 loss和L2 loss和Smooth L1 Loss的比较
  9. Jupyter的安装和使用(windows)
  10. 通过cURL获取web页面及http header信息