冒泡排序:可视化讲解与C语言实现

发布于:2025-08-12 ⋅ 阅读:(13) ⋅ 点赞:(0)

目录

介绍

算法工作原理

算法流程图

算法可视化展示

算法分步详解

流程图解析

算法推演

算法特性分析

时间复杂度

空间复杂度

稳定性

C语言实现


介绍

       冒泡排序是一种简单直观的排序算法,其核心思想是通过相邻元素比较和交换,使较大(或较小)的元素逐渐"浮"到数列的一端。本文以升序排列讲解,即每次遍历都会找出当前未排序区的最大元素放到已排序区。

算法工作原理

  1. 相邻元素比较:从数组的第一个元素开始,依次比较相邻的两个元素

  2. 交换位置:如果前一个元素大于后一个元素,则交换它们的位置(升序排序)

  3. 重复遍历:对数组进行多轮遍历,每轮遍历都会使当前未排序部分的最大元素"冒泡"到正确位置

  4. 终止条件:当某一轮遍历中没有发生任何交换时,说明数组已完全有序

算法流程图

算法可视化展示

算法分步详解

流程图解析

接下来以数组arr[8] = { 29,42,34,28,34,29,16,41 }来分步详解。

数组arr;数组长度n=8;

外层循环下标i初始值为0,满足i < n-1,每结束一次外层循环i++,直至不满足外层循环条件退出;

内层循环下标j初始值为0,满足 j < n-1-i,没结束一次内层循环j++,直至不满足内层循环条件退出;

标志位swapped用来标记此次内层循环是否存在元素交换,swapped在开始新的内层循环前被初始值为false,在内层循环中只要有元素交换,则被赋值为swapped。需要强调的是,整个数组可以被划分为未排序区+已排序区,如果在一整个内层循环,都没有元素交换,那么说明未排序区已经是有序的了;已排序区肯定是有序的;继而整个数组也是有序的了。因此,swapped可以用来快速验证数组是否排序完成,退出外循环,从而不必遍历外循环的所有i。对于那些原本就已经是"接近排序完成的数组",这可以缩短很多时间。

算法推演

以下是数组arr[8] = { 29,42,34,28,34,29,16,41 }初始化时的状态。

初始化i= 0,swapped=true,满足外循环条件,另swapped=false,j=0,开始一次内循环

在内循环中,此时j = 0,满足条件j < n - 1- i (此时i=0)

比较arr[0]和arr[1],29 < 42,不满足交换条件 swapped还是false

j++后变成1,继续比较arr[1]和arr[2]

此时42 > 34,满足交换条件,进行交换;同时令swapped=true

交换后如下所示

j++后变成2,继续比较arr[2]和arr[3]

42 > 28,满足交换条件,交换;同时令swapped=true

交换后如下图

j++后变成3,继续比较arr[3]和arr[4]

42 > 34 满足交换条件,执行交换;同时令swapped=true

交换后如下图

j++后变成4,继续比较arr[4]和arr[5]

42 > 29 满足交换条件,执行交换;同时令swapped=true

交换后如下图

j++后变成5,继续比较arr[5]和arr[6]

42 > 16 满足交换条件,执行交换;同时令swapped=true

交换后如下图

j++后变成6,继续比较arr[6]和arr[7]

42 > 41 满足交换条件,执行交换;同时令swapped=true

交换后如下图

j++后变成7   不满足j < n-1-i(n=8,i=0),则此次内循环结束;找到了未排序区中最大的一个,放置到已排序区中。接下来i++,(如果满足外循环条件)开启下一次外循环

最终排序完成后的数据顺序如下

算法特性分析

时间复杂度

情况 时间复杂度 说明
最优情况 O(n) 当输入数组已经完全有序时,优化代码(带swapped标志)只需一次遍历即可完成
平均情况 O(n²) 需要执行 n(n-1)/2 次比较操作
最坏情况 O(n²) 当输入数组完全逆序时,需要完整执行所有遍历 总比较次数为:(n-1)+(n-2)+...+1 = n(n-1)/2

空间复杂度

复杂度 说明
空间复杂度 O(1) 原地排序算法,只需要常数级别的额外空间(i,j,swapped)

稳定性

特性 结果 说明
稳定性 稳定 相等元素不会交换位置
// // 只有在前元素大于后元素时才交换(相等时,不会交换)
if (arr[j] > arr[j + 1]) 
{  
    // 交换操作
}
  • 当 arr[j] == arr[j+1] 时,条件不成立,不会执行交换

  • 相等元素保持原有相对顺序

  • 不会改变相同值元素的原始位置关系

C语言实现

#include <stdio.h>
#include <stdbool.h> // 使用布尔类型

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

void BubbleSort(int arr[], int n) {
    bool swapped; // 标记是否发生交换

    for (int i = 0; i < n - 1; i++) {
        swapped = false; // 每轮开始前重置标记

        for (int j = 0; j < n - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                // 交换元素
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                swapped = true; // 标记发生交换
            }
        }

        // 如果本轮没有发生交换,说明数组已有序
        if (!swapped) {
            break;
        }
    }
}

int main() {
    int arr[] = { 29,42,34,28,34,29,16,41 }; // 基本有序的数组
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("原始数组: ");
    printArray(arr, n);

    BubbleSort(arr, n);

    printf("排序后数组: ");
    printArray(arr, n);

    return 0;
}

代码输出