大家好ꔛ☆*゚!今天我为大家带来的文章是一篇关于C语言经典排序——冒泡排序的设计思路和函数实现。希望大家能够从我的文章中有所收获呀~😘 😘 😘
💡一、冒泡排序的思想
现在我们有这样一段乱序的数字,我们如何将它变得有序(升序或者降序)呢?
int arr[5] = { 3, 1, 5, 7, 4 };
这里我以将乱序数组改变为升序数组作为例子来讲解冒泡排序。
整体思路
首先我们想象一段数字升序排列,最大值在最右边,最小值在最左边,那么如果我们要完成数字的“拨乱反正”,我们就先将数组元素中的最大值找到并将之放于最后,而后将第二大的元素放在倒数第二位,这样往左排排到第二位为止(最后的一位数自然是最小的一个数了),排序停止,最后我们就得到了一段升序的数字。
arr[5] == { 1, 3, 4, 5, 7 };//arr的状态变为这样
冒泡排序的递归思考
经过上述的思考,我们发现我们一次次将较大的数字放在右边的操作可以通过递归的大事化小的思维改变为将数组不断缩小并将最大值排到最后,具体思路我以图像形式展现:
🔑二、算法实现
1.非递归的形式
上面提到,我们需要查找出数组中的最大数并将他排在最后一个位置上,然后缩小访问数组的元素个数,那我们该如何实现我们的想法呢?
这里直接设置循环从数组第一个元素开始访问,比较它与它后一位元素的大小,如果较大则交换两者的位置,否则直接继续读取下一元素,这样我们就能保证我们访问的元素是之前所有元素中最大的那个,并最终将较大值放到靠右的位置。我们接下来要将上界降低,于是发现一次循环是不够完成任务的,应该需要两层循环:外层的循环控制访问数组元素个数一次少一个,内层的循环具体来完成不断将极大值放到最后的操作。
具体实现如下:
#include <stdio.h>
void bubble_pai(int* arr)
{
int i = 0;
int j = 0;
for (i = 4; i > 0; i--)
{
for (j = 0; j < 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[5] = { 3, 1, 5, 7, 4 };
bubble_pai(arr);
for (int i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
二、递归形式
递归算法思想就是将问题逐步大事化小事的思想,根据上面我们编写的冒泡排序循环形式写法,想必聪明的你一定能将冒泡排序的递归算法完善出来,这里小狮子给出我自己的代码作为参考,但是希望初学C语言的同学还是能够多多自己思考代码,多多练习代码哦!
#include <stdio.h>
void bubble_pai(int* str, int n)
{
int exchange = 0;
if (0 <= n - 1)
{
for (int i = 0; i < n - 1; i++)
{
if (str[i] > str[i + 1])
{
int tmp = str[i];
str[i] = str[i + 1];
str[i + 1] = tmp;
exchange = 1;
}
}
if(exchange == 1) pai(str, n - 1);//如果这一步没有进行交换,那么就说明排序完成,可以直接结束递归
}
}
int main()
{
int arr[] = { 1,7,6,4,8,9,14,12,15,13 };
int n = sizeof(arr) / sizeof(arr[0]);
bubble_pai(arr, n);
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
🍀三、结语
在上面的内容中,我们一起学习了冒泡排序的思路和算法,想必你也发现了,上面给出的参考代码中还有许多可优化的地方,而且我在文章中只演示了将乱序变为升序,而除了升序,这些数组还可以转为降序,大家也可以思考一下该如何完成转降序的代码实现,希望大家多多思考并整理思路优化参考代码,经历了你的认真思考后,小狮子觉得你对冒泡排序的理解肯定会更上一层楼!
最后,希望各位同学都能日日有所得,事事顺己心,每天都有好心情呀✿◕‿◕✿