序言:当我们第一次接触排序算法时,绝大多数人学习的第一个算法都是冒泡排序。冒泡排序本身并不复杂,撰写此文主要是记录个人的学习心得,旨在为初学者提供一个入门视角,同时也供各位技术同仁茶余饭后轻松一阅。
1.冒泡排序初识
如果要用一句话来概括冒泡排序的精髓,那必定是:对相邻的两个元素进行两两比较。
理解了这个核心,再结合从左到右的多趟排序过程,你便可以想象:每个数字都像一个气泡,在比较中不断向右“上浮”,直至到达其正确的位置。
当然,以上只是一个通俗的理解。关于严格的定义和原理,网上已有大量资料,但我认为仍有必要在此明确一下:
基本原理:从序列的第一个元素开始,依次比较相邻的两个元素,如果它们的顺序错误(例如前一个大于后一个),就交换它们的位置。然后继续比较下一对相邻元素,重复此操作,直至序列末尾。(from Internet!! haha)
当然,我也搜索了相关的动图帮忙理解,动图如下:
2.冒泡排序的代码实现
2.1冒泡排序代码基础实现
冒泡排序的代码实现之前,有几个细节我想要强调一下:(假如传入长度是sz)
- 套在外层的循环,执行次数是
sz-1次,因为只剩一个的时候已经排序好了 - 嵌套在内层的循环则是根据外层执行的次数逐步减少,因为每执行一次,最右边都是已经排序好的,而左边没有排序的就是一个新的冒泡排序循环,执行的次数自然要减少(自己慢慢悟吧)
- 注意要传入
arr的长度sz,不要在函数内部计算,这一部分的内容我只能说传入arr数组本质上传入的是指针(地址),而不是真正的数组,这个需要到指针部分就可以理解了【这块的内容可以了解下一维数组传参】 - 针对
sz可以使用动态的计算方法:int sz = sizeof(arr) / sizeof(arr[0]);
基本的冒泡排序代码如下:
#include <stdio.h> void Bubble_Sort(int* arr, int sz) { for (int i = 0; i < sz - 1; i++) { for (int j = 0; j < sz - 1 - i; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } }2.2冒泡排序代码的优化
这个优化也没什么大不了的,就是针对已经完全排列好的特殊情况去掉后面的执行次数。简单来说就是如果这个数组已经是排好了的,那就只需要执行一次大排序就行了!
如何实现?用一个变量标记一下就行了!
void Bubble_Sort(int* arr, int sz) { for (int i = 0; i < sz - 1; i++) { int chg = 1; for (int j = 0; j < sz - 1 - i; j++) { if (arr[j] > arr[j + 1]) { chg = 0; int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } if (chg) break; } }当然完整的执行代码如下:大家可以仿照下面的代码尝试复现一下:里面还是藏了不少的小细节的,希望大家好好看看哟
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> void Bubble_Sort(int* arr, int sz) { for (int i = 0; i < sz - 1; i++) { int chg = 1; for (int j = 0; j < sz - 1 - i; j++) { if (arr[j] > arr[j + 1]) { chg = 0; int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } if (chg) break; } } void Print(int* arr, int sz) { for (int i = 0; i < sz; i++) { printf("%d ", *(arr + i)); } } int main() { int arr1[] = {3, 4, 2, 5, 6, 1}; int sz = sizeof(arr1) / sizeof(arr1[0]); Bubble_Sort(arr1, sz); Print(arr1, sz); return 0; }3.冒泡排序的优缺点
如果说用时间复杂度是O(N^2)来解释,那会很枯燥!!(空间复杂度?别杠了,这个可以忽略了)。简单来说冒泡排序的优点在于稳定而且可优化,但是缺点就是当遇到最坏的情况,面对庞大的数据依然要完整的遍历一遍,是非常的麻烦的!其实相邻交换这一块,插入排序是更好的,后面可以说
4.后记
这是我第一次尝试写博客,肯定会有不足之处,还请海涵!实话实说,网上完全不缺少关于这一块的知识,优秀的文章也不在少数。那我为什么要写,一方面我要为我的学习留下足迹,另一方面,针对最基础的内容,我也希望分享我的看法,同时让大家重视基础的重要性!或许只有写出来,才会有更深的感悟,也能让他人有所共鸣,也许这就是分享的意义吧!!
…哎,都是些废话感慨罢了,希望能够一直走下去