Skip to content

冒泡排序(Bubble Sort)

介绍

冒泡排序是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素, 如果它们的顺序错误就把它们交换过来。走访数列的工作是重复进行的,直到没有再需要交换的元素为止, 这时数列就完全排序好了。这个算法的名字由来是因为越小(或越大)的元素会经过交换慢慢“浮”到数列的顶端,故名冒泡排序。

拉胯

最容易理解,但也是最拉胯的排序算法。

动画模拟

工作原理

冒泡排序的基本思想是:通过对待排序序列从前向后(或从后向前),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底下的气泡一样逐渐向上冒。

具体来说,冒泡排序算法的执行过程如下:

  • 比较相邻的元素:如果第一个比第二个大(或小,根据排序顺序决定),就交换它们两个。
  • 对每一对相邻元素做同样的工作:从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大数(或最小数)。
  • 针对所有的元素重复以上的步骤:除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤:直到没有任何一对数字需要比较。

算法特性

稳定性: 冒泡排序是一种稳定的排序算法,即如果两个相等元素的相对位置在排序前和排序后保持不变。

时间复杂度:

  • 最优时间复杂度:O(n)(当输入数组已经是排序好的情况下,只需进行一次遍历即可确定数组已排序)。
  • 最坏时间复杂度:O(n^2)(当输入数组是逆序的情况下,需要进行n*(n-1)/2次比较和交换)。
  • 平均时间复杂度:O(n^2)。

空间复杂度: O(1)(因为冒泡排序是原地排序算法,不需要额外的存储空间)。

源码

vue
<script setup lang="ts">
import SortBarChart from "../comp/sort-bar-chart.vue";
import { onBeforeUnmount, ref } from "vue";
import { genRandArray, sortExchangeReact } from "../sort.util";
import { sleep } from "../../../utils/cmm.util";

const data = ref<number[]>(genRandArray(1, 100, 100));

const refreshData = () => {
  data.value = genRandArray(1, 100, 100);
};

const actives = ref<number[]>([]);
const stepInterval = ref<number>(20);
const sorting = ref<boolean>(false);

/**
 * 冒泡排序开始
 */
const sort = async () => {
  for (let i = data.value.length; i > 0; i--) {
    for (let j = 0; j < i - 1; j++) {
      actives.value = [j, j + 1];
      if (data.value[j] > data.value[j + 1]) {
        await sleep(stepInterval.value);
        sortExchangeReact(data.value, j, j + 1);
      }
    }
  }
};

onBeforeUnmount(() => {
  sorting.value = false;
});
</script>

<template>
  <div class="">
    <a-space direction="horizontal">
      <a-input-number v-model="stepInterval" :step="50" :min="5" style="width: 200px">
        <template #suffix>ms</template>
        <template #prefix> 步进间隔 </template>
      </a-input-number>
      <a-button @click="sort()">开始排序</a-button>
      <a-button @click="refreshData">刷新数据</a-button>
    </a-space>
    <div class="mt-sm" style="height: 300px">
      <sort-bar-chart :data="data" :actives="actives" />
    </div>
  </div>
</template>

<style scoped lang="less"></style>

MIT Licensed | fangjc1986@qq.com