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

时间:2014-12-08 12:45:35

标签: javascript bubble-sort

我传入元素数组[5,4,3]。冒泡排序设法推送5结束,这很好,但是当它循环第三次定位倒数第二个元素时,循环中断并返回错误的有序数组...不知道为什么,欢呼人< / p>

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;
    }

3 个答案:

答案 0 :(得分:1)

您需要为内循环和外循环使用单独的变量。退出内循环时,x将等于长度,因此外循环也将结束。

答案 1 :(得分:0)

您应该在内部和外部循环中使用单独的变量。在内循环中使用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;
}

背后的原因是变量提升

声明变量时,它分为两部分。一部分移动到它的范围之上,另一部分停留在它的位置。例如,

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

看起来像:

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
}

这就是代码中发生的事情。在两个循环中使用相同的变量使它们覆盖彼此的值。因此结果。

来自ECMAScript standard 5.1

  

变量语句声明按10.5中定义创建的变量。变量在创建时初始化为未定义。具有Initialiser的变量在执行VariableStatement时被赋予其AssignmentExpression的值,而不是在创建变量时。

有关详细信息,请参阅this MDN doc。寻找主题var hoisting。

<强>更新

使用具有块级范围的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;
}

答案 2 :(得分:0)

您对两个for-cycles使用相同的控件变量x,例如,应使用xy之类的不同。