冒泡在JavaScript中排序
冒泡排序是最广泛讨论的算法之一,仅仅因为它缺乏排序数组的效率。如果数组已经排序,冒泡排序将仅通过数组一次(使用下面的概念2),但最坏的情况是运行时间为O(N²),这是非常低效的。
甚至前总统巴拉克奥巴马也认识到泡泡排序效率低下。
当我们绘制O(N²)的增长率时,我们看到,与其他排序算法(如Merge Sort,即O(N Log N))相比,它的增长速度要快得多。
考虑到冒泡排序的暴行,理解算法并解读为什么它如此糟糕仍然很重要。
让我们深入研究冒泡排序的两个概念。
概念1
- 遍历数组并检查每个元素与数组中的下一个元素。
- 如果当前元素大于下一个元素,则交易所它们。
- 如果它不是更大,则向上移动指针并比较接下来的两个元素。
- 一旦我们到达数组的末尾,我们就知道最大元素位于最后一个位置。
- 重复此过程N次,其中N是数组的长度,每次迭代到最后排序的元素。
可视化概念1
让我们来看看这将如何在长度为6的数组上运行。
概念1代码
我们需要有两个指针(两个嵌套循环)用于概念1。每次迭代时,上限减1,因为我们知道这个索引包含一个排序值。
功能 bubbleSortConcept1(ARR) { 对于 (让 Ĵ = ARR。长度 - 1; Ĵ > 0; Ĵ-) { 对于 (让 一世 = 0; 一世 < Ĵ; 一世++) { 如果 (ARR(一世) > ARR(一世 + 1)) { 让 温度 = ARR(一世); ARR(一世) = ARR(一世 + 1); ARR(一世 + 1) = 温度; } } } }
概念2
- 遍历数组并检查每个元素与数组中的下一个元素。
- 如果当前元素大于下一个项目,则交易所它们。
- 表明已进行交易所。
- 如果发生交易所,则再次循环遍历阵列。
- 我们知道在没有发生交易所时对数组进行了排序。
概念2代码
我们只需要一个带有此方法的指针,因为我们使用变量来存储布尔值,指示是否发生了交易所。与概念1相反,这个概念要求我们在每次通过它时遍历数组中的每个项目。
功能 bubbleSortConcept2(ARR) { 让 换; 做 { 换 = 假; 安慰。日志(ARR); ARR。的forEach((项目, 指数) => { 如果 (项目 > ARR(指数 + 1)) { //将值保存到变量中,这样我们就不会丢失它 让 温度 = 项目; ARR(指数) = ARR(指数 + 1); ARR(指数 + 1) = 温度; 换 = 真正; } }) } 而 (换); }
运行
冒泡排序是O(N²)中效率最低的排序算法之一。在最坏的情况下,我们必须将每个元素与数组中的每个其他元素进行比较,因此为O(N²)。