From 2622a587165e305017afc5ae8ac1306643ae7c46 Mon Sep 17 00:00:00 2001 From: daiwanxing <377099119@qq.com> Date: Sun, 11 Jun 2023 14:29:44 +0800 Subject: [PATCH] docs: add new doc --- docs/.vitepress/config.js | 13 +- docs/articles/algorithm/bubble-sort.md | 175 +++++++++++++++++++++++++ docs/articles/algorithm/index.md | 6 +- 3 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 docs/articles/algorithm/bubble-sort.md diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index 275cf7ee..e7eca826 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -230,6 +230,17 @@ export default defineConfig({ ] } ], + "/articles/algorithm": [ + { + text: "Overview", + items: [ + { + text: "冒泡排序", + link: "/articles/algorithm/bubble-sort" + }, + ] + } + ], "/life/": [ { text: "My Life", @@ -263,7 +274,7 @@ export default defineConfig({ }, { text: "前端算法", - link: articleRef("algorithm"), + link: articleRef("algorithm/"), }, { text: "git常见操作", diff --git a/docs/articles/algorithm/bubble-sort.md b/docs/articles/algorithm/bubble-sort.md new file mode 100644 index 00000000..d519d895 --- /dev/null +++ b/docs/articles/algorithm/bubble-sort.md @@ -0,0 +1,175 @@ +# 冒泡排序 + +## 概念 + +冒泡排序核心概念在于每次都会对**相邻的两个数**进行比较 + +> 在升序排序的情况下,交换的条件需要满足,左边的数据**大于**右边的数据 +> +> 在降序排序的情况下,交换的条件需要满足,左边的数据**小于**右边的数据 + +冒泡排序的思想是每一次遍历未排序的数列后,都会将一个数据元素浮上去(这个数据会排序到左侧或者右侧,具体取决于升序还是降序)。 + +冒泡排序的需要 _N - 1_ 轮排序,其中 _N_ 为数组的长度 + +例如有一个如下的数组,长度为 5,那么总共需要 4 轮排序,每一轮排序都是左右两个数相互比较并判断是否需要交换位置。 + +```js +const data = [5, 1, 2, 9, -1]; +``` + +### 进行冒泡(升序)排序: + +- _第一轮_ + - `5` 与 `1` 进行比较,`5 > 1`,则两个数交换位置。 + ```js + // 最终排序结果 + [1, 5, 2, 9, -1]; + ``` + - `5` 与 `2` 进行比较, `5 > 2`,则两个数交换位置。 + ```js + // 最终排序结果 + [1, 2, 5, 9, -1]; + ``` + - `5` 与 `9` 进行比较, `5 < 9`,则不做处理。 + - `9` 与 `-1` 进行比较, `9 > -1`,则两个数交换位置。 + ```js + // 最终排序结果 + [1, 2, 5, -1, 9]; + ``` +- _第二轮_ + - `1` 与 `2` 进行比较,`1 < 2`,则不做处理。 + - `2` 与 `5` 进行比较,`2 < 5`,则不做处理。 + - `5` 与 `-1` 进行比较,`5 > -1`,则两个数交换位置。 + ```js + // 最终排序结果 + [1, 2, -1, 5, 9]; + ``` + - `5` 与 `9` 进行比较,`5 > 9`,则不做处理。 +- _第三轮_ + - `1` 与 `2` 进行比较,`1 < 2`,则不做处理。 + - `2` 与 `-1` 进行比较,`2 > -1`,则两个数交换位置。 + ```js + // 最终排序结果 + [1, -1, 2, 5, 9]; + ``` + - `2` 与 `5` 进行比较,`2 < 5`,则不做处理。 + - `5` 与 `9` 进行比较,`5 > 9`,则不做处理。 +- _第四轮_ + - `1` 与 `-1` 进行比较,`1 > -1`,则两个数交换位置。 + ```js + // 最终排序结果 + [-1, 1, 2, 5, 9]; + ``` + - `1` 与 `2` 进行比较,`1 < 2`,则不做处理。 + - `2` 与 `5` 进行比较,`2 < 5`,则不做处理。 + - `5` 与 `9` 进行比较,`5 > 9`,则不做处理。 + +最终执行了四轮排序操作,至此整个冒泡排序结束。 + +排序后的最终结果:`[-1, 1,2, 5, 9]`。 + +## 算法实现(JavaScript) + +可以看出,每次进行新一轮排序,都是两个相邻的数彼此判断是否需要交换位置,那么需要用到两个 for 循环。 + +外层的 for 循环负责遍历新一轮排序,内层的 for 循环负责交换新一轮排序下的元素。 + +代码实现如下: + +```js +function bubbleSort(data) { + const len = data.length; + // 前面提到过,冒泡排序最终需要进行 N - 1 轮排序,其中 N 为数组的长度 + const sortCount = len - 1; + for (let i = 0; i < sortCount; i++) { + for (let j = 0; j < len; j++) { + if (data[j] > data[j + 1]) { + const temp = data[j]; + data[j] = data[j + 1]; + data[j + 1] = temp; + } + } + } + return data; +} +``` + +执行该函数得到以下的输出结果: + +```js +bubbleSort([5, 1, 2, 9, -1]); // [-1, 1,2, 5, 9] +``` + +## 着手优化 + +这种为了交换数据,开辟一个临时变量的做法不能说不好,但是还能更简洁(装逼)的做法: + +原方案: + +```js{3-5} +function bubbleSort(data) { + //... + const temp = data[j]; + data[j] = data[j + 1]; + data[j + 1] = temp; + ///... +} +``` + +改进后: + +```js{3} +function bubbleSort(data) { + // ... + [data[j + 1], data[j]] = [data[j], data[j + 1]]; + // ... +} +``` + +我们还可以借助位运算,达到更快的值交换: + +```js +data[j] ^= data[j + 1]; +data[j + 1] ^= data[j]; +data[j] ^= data[j + 1]; +``` + +## 更进一步优化 + +通过上面的排序步骤示例,我们不难看每一轮比较完毕后,*排序好的数据*不再参与任何的位置交换。 + +每一轮比较,参与比较的数据的个数 = 总轮数 - 当前的轮数,也就是说我们不必每一轮都需要将数组中的每个元素进行比较,这是毫无意义的。 + +而且当数据量过大时,排序耗时会很长。 + +下面是优化后的排序算法: + +```js{6} +function bubbleSort(data) { + const len = data.length; + const sortCount = len - 1; + for (let i = 0; i < sortCount; i++) { + // 内循环每次需要比较的个数为总个数减去当前的趟数 + for (let j = 0; j < len - i; j++) { + if (data[j] > data[j + 1]) { + [data[j + 1], data[j]] = [data[j], data[j + 1]]; + } + } + } + return data; +} +``` + +## 算法复杂度 + +**时间复杂度**: O(n2) + +**空间复杂度**: O(1) + + +## 总结 + +冒泡排序是一种最基础、也是性能最低的排序算法,因为它的时间复杂度取决于数组的长度,数组越大,其排序的性能也就越低。 + +一般不会用到这个算法,但是了解它的核心概念是非常重要的。 \ No newline at end of file diff --git a/docs/articles/algorithm/index.md b/docs/articles/algorithm/index.md index b0ade6dd..22eb9b3e 100644 --- a/docs/articles/algorithm/index.md +++ b/docs/articles/algorithm/index.md @@ -1 +1,5 @@ -# 一些业务中可能会用到的算法整理 \ No newline at end of file +# 算法 + +### 排序算法 + +- [冒泡排序(Bubble Sort)](/articles/algorithm/bubble-sort)