张赐荣——一位视障程序员。
赐荣小站: www.prc.cx

張賜榮

张赐荣的技术博客

博客园 首页 新随笔 联系 订阅 管理

详解 C/C++ 实现冒泡排序算法

作者:张赐荣

先讲一下冒泡排序
冒泡排序是众多排序算法中最简单的一种,它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小)错误就把他们交换过来。
走访元素的工作是重复地进行的,直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就类似于水中冒泡,较大的数沉下去,较小的数慢慢冒起来,假设从小到大,即为较大的数慢慢往后排,较小的数慢慢往前排,故称为“冒泡排序(Bubble Sort)”。
冒泡排序的原理是:从左到右,相邻元素进行比较。每次比较一轮,就会找到序列中最大的一个或最小的一个。这个数就会从序列的最右边冒出来。
以从小到大排序为例,第一轮比较后,所有数中最大的那个数就会浮到最右边;第二轮比较后,所有数中第二大的那个数就会浮到倒数第二个位置……就这样一轮一轮地比较,最后实现从小到大排序。
比如对下面这个序列进行从小到大排序:
90  21  132  -58  34
第一轮:
1) 90 和 21比,90>21,则它们互换位置:
21  90  132  -58  34
2) 90 和 132 比,90<132,则不用交换位置。
3)132 和 –58 比,132>–58,则它们互换位置:
21  90  -58  132  34
4)132 和 34 比,132>34,则它们互换位置:
21  90  -58  34  132
到此第一轮就比较完了。第一轮的结果是找到了序列中最大的那个数,并浮到了最右边。
比较时,每轮中第 n 次比较是新序列中第 n 个元素和第 n+1 个元素的比较(假如 n 从 1 开始)。
第二轮:
1) 21 和 90 比,21<90,则不用交换位置。
2) 90 和 –58 比,90>–58,则它们互换位置:
21  -58  90  34  132
3) 90 和 34 比,90>34,则它们互换位置:
21  -58  34  90  132
到此第二轮就比较完了。第二轮的结果是找到了序列中第二大的那个数,并浮到了最右边第二个位置。
第三轮:
1) 21 和 –58 比,21>–58,则它们互换位置:
-58  21  34  90  132
2) 21 和 34 比,21<34,则不用交换位置。
到此第三轮就比较完了。第三轮的结果是找到了序列中第三大的那个数,并浮到了最右边第三个位置。
第四轮:
1) –58 和 21 比,–58<21,则不用交换位置。
至此,整个序列排序完毕。从小到大的序列就是“–58 21 34 90 132”。从这个例子中还可以总结出,如果有 n 个数据,那么只需要比较 n–1 轮。而且除了第一轮之外,每轮都不用全部比较。因为经过前面轮次的比较,已经比较过的轮次已经找到该轮次中最大的数并浮到右边了,所以右边的数不用比较也知道是大的。

比较过程总结如下(升序(由小到大):
每次比较相邻两数,小的交换到前面,每轮结束后最大的数交换到最后。
1、比较相邻的元素。如果第一个比第二个大(小),就交换他们两个。
2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大(小)的数。
3、针对所有的元素重复以上的步骤,除了最后已经选出的元素(有序)。
4、持续每次对越来越少的元素(无序元素)重复上面的步骤,直到没有任何一对数字需要比较,则序列最终有序。

下面的程序演示了如何用 C/C++ 编写基本的冒泡排序算法。

#include <stdio.h>

int PrintNumArray(int num[], int length); // 声明打印整型数组的函数
int sort_Ascending(int num[], int length); // 声明升序排列函数
int sort_Descending(int num[], int length); // 声明降序排列函数

int main(void)
{
int sz[] = { 9,0,8,5,7,1,4,3,6,2 }; // 定义一个数组保存带排序的数
printf("未排序前数组: ");
PrintNumArray(sz, 10); // 打印未排序前的数组
printf("升序排列: ");
sort_Ascending(sz, 10); // 调用冒泡排序对数组进行从小到大(升序)排列
PrintNumArray(sz, 10); // 打印升序排列后的数组
printf("降序排列: ");
sort_Descending(sz, 10); // 调用冒泡排序对数组进行从大到小(降序)排列
PrintNumArray(sz, 10); // 打印降序排列后的数组
getchar(); // 暂停程序
return(0);
}

int PrintNumArray(int num[], int length) // 打印整型数组
// num 数组名,length 数组长度
{
for (int loop = 0;loop < length;loop++)
{
printf("%d;", num[loop]);
}
printf("\n");
return(length);
}

int sort_Ascending(int num[], int length) // 冒泡排序升序(从小到大)
{
for (int x = 0;x < length;x++)
{
for (int y = 0;y < length - (x + 1);y++)
{
if (num[y] > num[y + 1]) // 用 大于号 做比较为升序排列
{
int t = num[y];
num[y] = num[y + 1];
num[y + 1] = t;
}
}
}
return(length);
}

int sort_Descending(int num[], int length) //冒泡排序降序(从大到小)
{
for (int x = 0;x < length;x++)
{
for (int y = 0;y < length - (x + 1);y++)
{
if (num[y] < num[y + 1]) // 用 小于号 做比较为降序排列
{
int t = num[y];
num[y] = num[y + 1];
num[y + 1] = t;
}
}
}
return(length);
}

posted on 2022-02-19 07:18  张赐荣  阅读(239)  评论(0编辑  收藏  举报

感谢访问张赐荣的技术分享博客!
博客地址:https://cnblogs.com/netlog/
知乎主页:https://www.zhihu.com/people/tzujung-chang
个人网站:https://prc.cx/