简体   繁体   English

js冒泡排序未正确处理所有元素

[英]js Bubble sort not processing all elements correctly

I pass in elements array [5,4,3]. 我传入元素数组[5,4,3]。 The bubble sort manages to push 5 the end, this is fine, but when it loops through a third time to locate the second to last element, the loop breaks and the incorrect ordered array is returned... not sure why, cheers guys 冒泡排序设法将5推到最后,这很好,但是当它第三次循环以查找倒数第二个元素时,循环中断并且返回了不正确的有序数组...不知道为什么,干杯

this.bubbleSort = function (elements) {

        //Loop through to the second to last index. By the time we get to the last index, its already //been compared with what’s in front of it
        var hasHadChange;
        for (var x = 0; x < elements.length - 1; x++) {
            hasHadChange = false;

            //Loop through to the second to last index.
            for (var y = 0; y < elements.length - 1; y++) {

                //Check the current item(x) in the array plus the item next to current item (x+1), if its larger
                if (elements[y] > elements[y + 1]) {

                    //Acknowledge there has been a change
                    hasHadChange = true;

                    //Swap the items around
                    var temp = elements[y];
                    elements[y] = elements[y + 1];
                    elements[y + 1] = temp;
                    //This continues until the largest value has bubbled to the right
                }
            }
        }
        return elements;
    }

You need to use separate variables for the inner and the outer loop. 您需要为内部和外部循环使用单独的变量。 When you exit the inner loop, x will be equal to the length, so the outer loop will end also. 退出内循环时, x等于长度,因此外循环也将结束。

You should use separate variables in inner and outer loops. 您应该在内外循环中使用单独的变量。 Using y in inner loop instead will give you the correct answer. 在内部循环中使用y可以为您提供正确的答案。

var bubbleSort = function (elements) {

    //Loop through to the second to last index. By the time we get to the last index, its already //been compared with what’s in front of it
    var hasHadChange;
    for (var x = 0; x < elements.length - 1; x++) {
        hasHadChange = false;

        //Loop through to the second to last index.
        for (y = 0; y < elements.length - 1; y++) {

            //Check the current item(x) in the array plus the item next to current item (x+1), if its larger
            if (elements[y] > elements[y + 1]) {

                //Acknowledge there has been a change
                hasHadChange = true;

                //Swap the items around
                var temp = elements[y];
                elements[y] = elements[y + 1];
                elements[y + 1] = temp;
                //This continues until the largest value has bubbled to the right
            }
        }
    }
    return elements;
}

The reason behind this is variable hoisting . 其背后的原因是可变吊装

When a variable is declared, it breaks into two parts. 声明变量后,它分为两部分。 One part moves to top of it's scope, other stays at it's position. 一部分移至其作用域的顶部,另一部分则保持在其位置。 For Example, 例如,

function foo() {
    if (false) {
        var x = 1;
    }
    var y = 1;
}

Will look like : 看起来像:

function foo() {
    var x = undefined;  //Declaration of x is hoisted
    var y = undefined;   //Declaration of y is hoisted
    if (false) {
        x = 1; //Assignment still occurs where we intended
    }
    y = 1; //Assignment still occurs where we intended
}

This is what happened in the code. 这就是代码中发生的事情。 Using same variable in both loops makes them overwrite each other values. 在两个循环中使用相同的变量会使它们彼此覆盖值。 Hence the result. 因此,结果。

From ECMAScript standard 5.1 : ECMAScript标准5.1开始

A variable statement declares variables that are created as defined in 10.5. 变量语句声明按10.5定义创建的变量。 Variables are initialised to undefined when created. 变量在创建时初始化为未定义。 A variable with an Initialiser is assigned the value of its AssignmentExpression when the VariableStatement is executed, not when the variable is created. 在执行VariableStatement时(而不是在创建变量时),将为带有Initialiser的变量分配其AssignmentExpression的值。

See this MDN doc for more details. MDN文档了解更多详情。 Look for topic var hoisting. 寻找主题var提升。

Update 更新

Using let which has block level scope, you can have variable x in both loops. 使用具有块级作用域的let ,您可以在两个循环中都有变量x

var bubbleSort = function (elements) {

    //Loop through to the second to last index. By the time we get to the last index, its already //been compared with what’s in front of it
    var hasHadChange;
    for (var x = 0; x < elements.length - 1; x++) {
        hasHadChange = false;

        //Loop through to the second to last index.
        for (let x = 0; x < elements.length - 1; x++) {

            //Check the current item(x) in the array plus the item next to current item (x+1), if its larger
            if (elements[x] > elements[x + 1]) {

                //Acknowledge there has been a change
                hasHadChange = true;

                //Swap the items around
                var temp = elements[x];
                elements[x] = elements[x + 1];
                elements[x + 1] = temp;
                //This continues until the largest value has bubbled to the right
            }
        }
    }
    return elements;
}

您在两个for循环中使用相同的控制变量x ,例如应使用xy类的变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM