【算法基础】冒泡排序解析

162 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情

​作者:[柒号华仔]

个人信条:星光不问赶路人,岁月不负有心人。

个人方向:专注于5G领域,同时兼顾其他网络协议,编解码协议,C/C++,linux等,感兴趣的小伙伴可以关注我,一起交流。


1. 冒泡排序介绍

1.1 定义

在我们日常喝可乐雪碧的过程中,会看见无数气泡向水面移动,直到冒出水面,气泡比水轻会向前移动,我们称这种现象为冒泡。在我们数组排序中,每一个数组元素根据大小比对,小的元素不断向前移动,如同气泡在冒出一样,我们称这种排序方法为冒泡排序。

冒泡排序重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

1.2 基本原理

冒泡的原理如下:

  1. 比较相邻的两个元素,如果第一个比第二个大,就两者进行交换,如果第一个比第二个小,则保持顺序不变。 
  2. 对数组中的每一对相邻元素依次做上面的比对和交换工作,这样最大的数就移到了最后。
  3. 一轮完毕后,继续重复步骤1和步骤2的操作,直到没有任何一对数字需要比较,最后便得到了依次排序好的数组。

下面的动图非常清晰的诠释了冒泡排序的过程:

冒泡.gif

1.3 时间复杂度

如果数组是正序排列的,一轮比对即可完成排序,此时时间复杂度为O(n);

如果数组是完全倒序的,需要进行n-1轮排序,每一轮要进行n-i次比对。这里的i是已经比对的轮次数,也是数组末尾已经排序好元素个数。总的比对次数为: (n-1)+(n-2)+...+1=n*(n-1)/2 此时时间复杂度为O(n2n^2);

因此,冒泡排序的平均时间复杂度为O(n2n^2) 。

1.5 优缺点

优点:冒泡排序算法简单,稳定可靠。

缺点:当数据量庞大并且乱序严重时,比较次数多,排序效率低。

2. 代码实现

2.1 代码设计

a. 实现冒泡排序需要设计两层循环,外循环为总的比对轮次,内循环为未排列好的元素;

b. 取出待比对元素array[i],将其与array[i+1]进行比对,若前者比后者大,则进行交换,否则不进行交换。

c. 依次重复向后比对,直至这一轮比对交换完,再从头进行下一轮。

d. 总共进行size轮比对,排序完成

2.2 代码实现

#include <stdio.h>
  
void printArray(int array[], int size) {
    int i;
    for (i = 0; i < size; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
}

void bubble_sort(int array[],int size){
    int temp,i,j;
    for(i = 0;i < size-1;i++){
        for (j = 0;j < size-1-i;j++){
            if (array[j] > array[j+1]) {
                temp = array[j];
                array[j] = array[j+1];
                array[j+1] = temp;
            }
        }
    }
}
int main(){
    int array[] = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};

    bubble_sort(array,sizeof(array)/sizeof(int));
    printArray(array,sizeof(array)/sizeof(int));

    return 0;
}

运行结果:

image.png