冒泡排序介绍
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行,直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。——来自百度百科
图文解析
我们举一个简答的例子,现在有如下五个方块,需要将将它们从低到高升序排序。
我们现在详细演示一遍第一趟的内容:
第三步结束后:
第四步过后,第一轮结束:
总结规律:
1.每一轮结束后,最大的方块会移动到最右边,即可以将一块方块归位。
2.对n个数据进行冒泡排序,需要排序n-1轮
3.每次完成一轮后,下一轮需要比较的数据减少1。(比如我们这里,第一轮完成后,最大的数据就会道达右边,下一轮就可以少比较一次)
每一轮的结果演示:
第一轮:
第二轮:
排序完成!
可视化演示
将71,114,105,62,44,47,93,80,56,121
这十个数通过冒泡排序进行升序排序:
冒泡排序C语言实现(一般方法)
最简单的方法,遍历数组,满足条件则替换。
代码
#include <stdio.h>
void bubble_sort(int arr[], int sz)
{
//进行sz-1轮排序
for (int i = 0; i < sz - 1; i++)
{
//每一轮比较sz-1-i次(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;
}
}
}
}
int main()
{
int arr[10] = { 71,114,105,62,44,47,93,80,56,121};
int sz = sizeof(arr) / sizeof(arr[0]);
printf("排序前: ");
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
bubble_sort(arr, sz);
printf("\n排序后(升序): ");
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
程序运行效果:
思考一下优化方案
我们现在代码的缺点:
1.可能还没有完全循环完就已经排序好了,就想我们上面的图解,只进行了两轮就排序好了,于是我们通过自己的判断让排序停止了。但是我们写的程序不会这样做,所以我们第一步优化方案就是加一个标记来标记是否已经排序完毕,这里我们的逻辑是:如果进行了交换,则没有排序完毕,否则就代表已经排序完成
2.很难想到的一点,我在参考了一位大佬的做法后,总结一下。请看上方我们第一轮结束时的图片:
第二轮,需要比较三次((n-1-i)=(5-1-1))
但是我们实际只需比较一次即可,因为右方的4,5已经有序了。
所以我们有了第二个优化方案:每一轮结束后,标记最后一次交换的位置,其右侧为有序,左侧为无序。我们只需要判断无序的位置即可。
优化后代码:
#include <stdio.h>
void bubble_sort(int arr[], int sz)
{
//有序数的边界(我们只需判断其左侧的无序数)
int limit = sz - 1;
//标记每一轮最后一次交换的位置
int last_change = 0;
//进行sz-1轮排序
for (int i = 0; i < sz - 1; i++)
{
//假设没有进行替换(数组已经有序)
int flag = 0;
//每一轮比较limit次,即只比较无序的数
for (int j = 0; j < limit; j++)
{
if (arr[j] > arr[j + 1])
{
//交换
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
//如果交换了,则标记数组无序
flag = 1;
//记录最后一次交换的位置
last_change = j;
}
}
//每一轮结束后,更新有序数的边界,其边界就是上一轮最后一次交换的位置
limit = last_change;
//如果没有交换,则数组已经有序,直接跳出循环
if (0 == flag)
{
break;
}
}
}
int main()
{
int arr[10] = { 71,114,105,62,44,47,93,80,56,121 };
int sz = sizeof(arr) / sizeof(arr[0]);
printf("排序前: ");
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
bubble_sort(arr, sz);
printf("\n排序后(升序): ");
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
程序运行效果:
总结
冒泡排序是一个稳定的算法,也是比较简单的算法,希望大家能够尽早掌握。本篇博客主要介绍了冒泡排序的一般形式和优化方法,希望对你有所帮助!
文章如果有问题请大家积极在评论区讨论,一起讨论一起进步!
那我们下期再见吧!