八大排序------冒泡排序
在C语言的学习中我们在学完基本语句后,第一个接触到的逻辑结构就是排序,相比于其他排序,冒泡排序的逻辑思想,代码实现是非常简单这一期我们就详细讲解一下冒泡排序。
初步了解冒泡排序的逻辑思想
**冒泡排序:**直观的呈现在我们面前就是相邻两数比较大小,如果前数大于后数,则两数交换位置;反之不发生交换。如此循环,直到最后两个数比较完大小是否发生完交换,此时我们就是完成了一次循环(后面要讲到的内层循环)。
第一次循环的目的是将最大的那个数移动到最后一位。
以后的每次循环就是将剩下的数中最大的排在这组数的最后
我们在这里举个例子,一个随机数组{ 3,4,1, 8,5, 9,6, 2,7}
第一次操作比较3与4的大小,较大数位于后面则不变换位置
第二次操作比较4与1 的大小
前者大于后者位置交换
继续重复上述操作:后者大于前者不发生交换
后者小于前者发生交换
后者大于前者不发生交换
后者小于前者发生交换
后者小于前者发生交换
后者小于前者发生交换
此时数字9就到达它最终的位置这个时候第一次循环完成!
上述操作就是一次循环的结果,将最大数放到最后一个位置,如果我们想将整个数组升序排列,继续重复上述循环即可,以上就是冒泡排序的基本逻辑思路
冒泡排序的代码实现
再了解了上述的冒泡逻辑之后我们来看一看代码的实现
#include <stdio.h>
void Bubble_sort(int arr[], int size)
{
int j, i, tem;
for (i = 0; i < size - 1;i++)//size-1 是因为不用与自己比较,所以比的数就少一个
{
int count = 0;
for (j = 0; j < size - 1 - i; j++)
{
if (arr[j] > arr[j + 1]) //后数小于前面的数进行交换
{
tem = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tem;
count = 1; //count = 1 证明发生了交换
}
}
if (count == 0) //如果某一趟没有交换位置,则说明已经排好序,直接退出循环
break;
}
}
int main()
{
int arr[9] = { 3,4,1,8,5,9,6,2,7 };
printf("排序前的数组:\n");
for (int i = 0;i < 9;i++)
{
printf("%d ", arr[i]);
}
printf("\n");
printf("排序后的数组:\n");
Bubble_sort(arr, 9);
for (int i = 0;i < 9;i++)
{
printf("%d ", arr[i]);
}
return 0;
}
运行结果如下:
现在我们把这个排序推广到任意十个数进行排序
代码实现如下:
#include <stdio.h>
void Bubble_sort(int arr[], int size)
{
int j, i, tem;
for (i = 0; i < size - 1;i++)//size-1 是因为不用与自己比较,所以比的数就少一个
{
int count = 0;
for (j = 0; j < size - 1 - i; j++) //size-1-i是因为每一趟就会少一个数比较
{
if (arr[j] > arr[j + 1])
{
tem = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tem;
count = 1;
}
}
if (count == 0) //如果某一趟没有交换位置,则说明已经排好序,直接退出循环
break;
}
}
int main()
{
int arr[10] = {0};
printf("请输入十个数:\n");
for (int i = 0;i < 10;i++)
{
scanf("%s", arr[i]);
}
printf("排序前的数组:\n");
for (int i = 0;i < 10;i++)
{
printf("%d ", arr[i]);
}
printf("\n");
printf("排序后的数组:\n");
Bubble_sort(arr, 10);
for (int i = 0;i < 10;i++)
{
printf("%d ", arr[i]);
}
return 0;
}
代码调试如下:
冒泡排序复杂度分析:
时间复杂度:
最好的情况下:所有的数都有序排列。我们每次进入到循环中时只需要判断两个大小,发现前数一直小于后数,不需要交换,此时的时间复杂度也就是遍历完整个数组的时间复杂度也就是O(n)。
最坏的情况下:最坏的情况就是数组逆序排列,第一次我们遍历完整个数组需要(n-1)次,第二次遍历需要(n-2)次,…… 以此类推。 此时我们需要进行比较的次数是n(n−1)/2次,当然移动的次数也是等量级的,此时时间复杂度为O(n^2)。