Javascript 为什么在冒泡排序算法的内部循环中使用'length-i-1'

Javascript 为什么在冒泡排序算法的内部循环中使用'length-i-1',javascript,algorithm,bubble-sort,Javascript,Algorithm,Bubble Sort,使用javascript,它被编程为按asc顺序对数组中的元素进行排序。我尽力理解为什么内环使用length-I-1,但无法理解。有人能帮我理解为什么我们要用它吗 function bubbleSort(arr) { for(let i=0; i<= arr.length; i++) { for(let j=0; j< arr.length-i-1; j++) { if(arr[j] > arr[j+1]) {

使用javascript,它被编程为按asc顺序对数组中的元素进行排序。我尽力理解为什么内环使用
length-I-1
,但无法理解。有人能帮我理解为什么我们要用它吗

function bubbleSort(arr) {

    for(let i=0; i<= arr.length; i++) {
        for(let j=0; j< arr.length-i-1; j++) {
            if(arr[j] > arr[j+1]) {
                let lesser = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = lesser;
            }
        }
    }

    return arr;
}
函数bubbleSort(arr){
对于(设i=0;i arr[j+1]){
设lesser=arr[j+1];
arr[j+1]=arr[j];
arr[j]=较小值;
}
}
}
返回arr;
}

正如Daniel在评论中所说,这是因为这些项目已经被排序(例如,在第一次迭代中以最高索引结束的最大元素)

观看下面的gif,注意8是如何在最右边结束的,然后被黑框包围,表示它不再需要移动,因此不再需要检查(它大于长度-i-1)

不检查这些已经“锁定”的元素有助于提高算法速度


Gif来自:

让我们从以下步骤来考虑: 假设您有一个包含10个元素的数组,只是为了举例

第一步

i = 0, j goes from 0 to 9( = 10 - 0 - 1)
i = 1, j goes from 0 to 8( = 10 - 1 - 1)
所以它遍历整个数组。 现在,每次我们看到当前元素大于下一个元素时,我们都会切换它们(通过
if(arr[j]>arr[j+1])
),因此在第一次迭代结束时,在最后一个位置,我们将得到数组的最大元素

第二步

i = 0, j goes from 0 to 9( = 10 - 0 - 1)
i = 1, j goes from 0 to 8( = 10 - 1 - 1)

现在,我们可以注意到,我们省略了最后一个(第9个)位置,但我们知道它已经是上一步的最大值,因此它位于正确的位置。在本次迭代结束时,我们将在第8个位置设置第二个最大元素,并且该过程将继续。

编辑:手机上的速度太慢:p

在每次外部迭代之后,第i个最大元素位于正确的位置。所以在第一次迭代之后,最大的元素在最右边。现在我们知道了,我们不必在下一轮中比较这个元素。 在第二次迭代之后,第二大元素位于最右侧-1位置。所以这两个最大的元素已经排序了,我们不必在下一轮考虑它们。


用一个简单的例子试试你的算法,然后用手一步一步地完成。然后你应该看清楚。

索引大于
length-i-1
的所有内容都已排序。使用gif比使用单词更容易:d有时我认为这是学习此类内容的最简单方法!是的,但也有一些时候,为了理解一些东西,你应该努力学习每一个单词!