【排序算法】冒泡排序(C语言)
【排序算法】—— 冒泡排序
目录
- 一、冒泡排序的原理
- 二、代码实现
- 三、代码的优化
- 四、冒泡排序的效率
- 五、模仿库函数的qsort实现
- 1. 相关接口
- 2. 代码实现
一、冒泡排序的原理
冒泡排序法:(Bubble sort)是一种基础的交换排序,非常简单,一学就懂
对数组进行遍历,每次对相邻两个进行比较大小,若大的数值在前面则交换位置(升序),完成一趟遍历后数组中最大的数值到了数组的末尾位置,再对前面n-1个数值进行相同的遍历,一共完成n-1次遍历就实现了排序完成
- 第一趟对
0~n-1
遍历,依次对比前后的大小,若是不满足前小后大就交换,此时最大的数就被挪到了最后一个位置
- 对
0~n-2
遍历,继续比较前后大小,此时前n-2
个数中最大的数就到了倒数第二个位置
- 重复上述动作继续遍历,每一次都将最大的数向后挤,直到遍历完毕排序成功
二、代码实现
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. 相关接口
- 冒泡排序函数:
void bubble_sort(const void* base, const int length, const int size, int (*cmp)(void* e1, void* e2));
- 参数:
base
:被排序的数组,由void*类型指针接收,const不能改变指针指向的内容,但可以改变指针的指向length
:数组的长度,就是值的数量,由const限制不能改变大小size
:数组中存放的数值类型的字节大小,就是一个值占几个字节的空间,由const限制不能改变大小cmp
:数组中数据的比较规则,由cmp函数指针接收
- 交换数据函数:
将指针转换成char*,依次按照字节进行交换
void Swap(const void* e1, const void* e2, const int size);
- 参数:
e1
:被交换的数据的地址,由void*指针接收,由const限制不能改变指针指向,但可以改变指针指向的内容e2
:被交换的数据的地址,由void*指针接收,由const限制不能改变指针指向,但可以改变指针指向的内容size
:被交换数据类型的字节大小,由const限制不能改变大小
- 比较函数:数组中数值的比较规则
int cmp(const void* e1, const void* e2);
- 返回值:大于0,e1大;等于0,一样大;小于0,e2大
- 参数:
e1
:被比较的数据的地址,由void*指针接收,由const限制不能改变指针指向,但可以改变指针指向的内容e1
:被比较的数据的地址,由void*指针接收,由const限制不能改变指针指向,但可以改变指针指向的内容
- 函数体:
- 由用户自定义实现数值的比较规则
传参:
被比较数值的地址由void*指针接收
数值在数组中第 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. 代码实现
- 冒泡排序法的实现:
#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;}}
}
- 字符串数组升序排序的演示:
#include <stdio.h>
#include <string.h>
int test1(void)
{char* strs[] = {"abc", "def", "bpm", "jqx"};bubble_sort(strs, sizeof(strs), sizeof(char*), strcmp);//printf打印排序之后的内容
}
- 整型数组降序排序的演示:
#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语言)相关推荐
- C语言基础排序算法-冒泡排序
C语言基础排序算法-冒泡排序 什么是冒泡排序? 顾名思义,这种排序方法就像水中的气泡一样,从底逐渐往上冒,一次前进一步.我们来看一个例子,看看到底是怎么冒泡的.假设有一个数组3,2,5,4,1,我们希 ...
- 十种经典排序算法精粹(c语言版本)
下面给出这段时间我苦心研究验证过的十种经典排序算法的C语言版本,即下面的排序算法: 插入排序,shell排序,冒泡排序,快速排序,选择排序,堆排序,归并排序,桶排序,基数排序和计数排序.整理出来以作备 ...
- 常见排序算法(C语言实现)
常见排序算法(C语言实现) 文章目录 常见排序算法(C语言实现) 一.插入排序 二.希尔排序 三.选择排序 四.堆排序 五.冒泡排序 六.快速排序 七.归并排序 一.插入排序 void insertS ...
- 数据结构-排序算法(c语言实现篇)
数据结构-排序算法(c语言实现篇) 排序算法是非常常用的算法,从介绍排序的基本概念,到介绍各种排序算法的思想.实现方式以及效率分析.最后比较各种算法的优劣性和稳定性. 1 排序的概念及应用 1.1 排 ...
- 经典排序算法 - 冒泡排序Bubble sort
经典排序算法 - 冒泡排序Bubble sort 其原理是比较接近的数字22,按照从小到交换大或降序排列, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头開始进行两两比較交换,直到倒 ...
- 排序算法——冒泡排序(Bubble Sort)
排序算法--冒泡排序(Bubble Sort) 算法简介(Introduction) Bubble sort is to compare adjacent elements of the list a ...
- python排序算法 ——冒泡排序(附代码)
python排序算法 --冒泡排序 文章目录 python排序算法 --冒泡排序 一.前言 二.算法描述 三.代码实现 总结 一.前言 相关知识来自<python算法设计与分析>.初级排序 ...
- 十大经典排序算法-冒泡排序算法详解
十大经典排序算法 十大经典排序算法-冒泡排序算法详解 十大经典排序算法-选择排序算法详解 十大经典排序算法-插入排序算法详解 十大经典排序算法-希尔排序算法详解 十大经典排序算法-快速排序算法详解 十 ...
- 小白学六大排序算法(C语言版)
今天在csdn刷blink的时候,刷到一个冒泡排序的吐槽,看了看评论区,发现不少人分不清选择排序和冒泡排序,笔者想了一下,发现这两个排序确实相似度蛮高的,所以总结了c语言里涉及到六个排序算法,笔者才疏 ...
- 排序算法---冒泡排序(java版)
冒泡排序 原理 冒泡排序(Bubble Sort)是一种简单的排序算法,它通过依次比较两个相邻的的元素,看两个元素是否满足大小关系要求,如果不满足则交换两个元素.每一次冒泡会让至少一个元素移动到它应该 ...
最新文章
- 优词词根词典mdx_推荐|一波好用的在线英语词典网站
- android 稳定性测试工具,APP 稳定性测试工具-Fastbot_Android详解
- 北京2019高考分数线:本科理423文480
- 每一个项目都可以有一个项目blog page
- ubuntu下修改用户的默认目录
- postgresql 修改表字段_关于一些postgresql特有的概念以及安装方法的叙述
- 寒假作业3(传说中的写软件)
- [Noip2007]Core树网的核
- Vue CLI 3 中文文档
- Raki的读paper小记:How to Fine-Tune BERT for Text Classification?
- linux性能监控命令dstat详解【杭州多测师_王sir】【杭州多测师】
- 轻量级架构和重量级架构
- 2021 年 15 款适用于 PC 和 Mac 的最佳 Android 模拟器
- 教你如何使用语雀提高效率
- 不羁野草挑战遗传法则
- Python 中的取余与取整操作
- [Swift]代码触发UIButton的点击事件
- java join的用法
- jmeter 压测java代码
- Android OpenGL ES 画球体