前言
在数据结构中有许多种排序,我接触到的第一种就是冒泡排序,其实冒泡排序在性能上面是很差的,但是了解和熟悉它对增强我们的代码能力并且对排序有一定的浅显的认识。下面让我们一起来了解一下冒泡排序吧!
目录
1.冒泡排序的思想
2.冒泡排序的图解
3.冒泡排序的代码实现
4.细节讲解
5.冒泡排序的时间复杂度
1.冒泡排序的思想
排序是我们最常见的算法之一,生活中的很多地方都用到了排序。比如我们网购某件商品的时候就会选择按照某种我们关注的事物排序,有可能是销量,价格亦或者是综合等等。冒泡排序的就是一种简单的排序,那么它是怎么样进行排序的呢?如果你是要对一个长度为n的数组排升序,那么第一次就要从前向后遍历数组来比较两个相邻的数,如果前一个数比后一个数大就交换这两个数,直到遍历完数组的最后一个元素,这就是第一趟冒泡排序,我们已经将最大的数字放到了数组的最后一个元素,下一趟只需要 只需要遍历前n-1个元素,(因为第一趟冒泡排序已经将最大的字排到了数组的最后位置)这次也是如法炮制,如果前一个数大于后一个数的话就交换这两个数,下一次就只需要遍历前n-2个数组,每趟冒泡排序都能够将一个数字排好,那么每进行一次冒泡排序需要排的数组元素都会-1,直到最后一次只剩下一个数字冒泡排序就结束了,这时数组有序,如果是排降序也是一样的。这种每次都有一个元素冒出的排序很像是泡泡一样不断的冒出来,因此形象的称它为冒泡排序。
2.冒泡排序的图解
3.冒泡排序的代码实现
#include<assert.h>
void BubbleSort(int arr[], int n)
{
assert(arr);//防止指针为空
int i = 0;
int k = n;
for (i = 1; i < n; i++)//一共进行冒泡排序的次数
{
int j = 0;
for (j = 0; j < k-1; j++)//每趟冒泡排序的进行
{
if (arr[j] > arr[j+1])//如果前一个数大于后一个数就交换
{
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
k--;//控制每次冒泡排序的数组元素个数
}
}
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1 };
BubbleSort(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
4.细节讲解
冒泡排序还有其他的实现方式,我认为上述的比较简单所以就写了上述的这种。如果想要将数组排序成升序,但是这个数组已经是升序(有序的了)或者经过程序排列几次后已经变为有序,这个时候是不需要再排序了,但是程序依旧会执行,前后元素的比较也会进行,这时候是没必要的,这种情况我们思考是不是应该优化一下程序呢,如果程序已经有序了那么就可以结束程序了。
程序使用了assert()函数来判断指针arr是否为空,如果arr为空程序就不会执行,可以提示我们哪里出错了。
#include<assert.h>
void BubbleSort(int arr[], int n)
{
assert(arr);//防止指针为空
int i = 0;
int k = n;
for (i = 1; i < n; i++)//一共进行冒泡排序的次数
{
int flag = 0;//设置一个标志
int j = 0;
for (j = 0; j < k-1; j++)//每趟冒泡排序的进行
{
if (arr[j] > arr[j+1])//如果前一个数大于后一个数就交换
{
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
flag = 1;
}
}
if (0 == flag)//说明此时数组已经排好序
break;//结束循环
k--;//控制每次冒泡排序的数组元素个数
}
}
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1 };
BubbleSort(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
5.冒泡排序的时间复杂度
通过前面的讲解我们知道了如果一个数组的长度是n每趟冒泡排序都能将一个元素排成有序,那么就需要n-1趟,第一趟遍历数组的n个元素,第二趟遍历数组前n-1个元素,第三趟遍历前n-2个元素,一次类推,一共遍历的躺数就是一个从n到1的等差数列,公差为1(也可认为是从n到2),
那么时间复杂度就为O(n^2)。