为什么这个列表分拣机会崩溃?

时间:2014-01-18 23:23:40

标签: javascript algorithm sorting crash logic

此页面在运行时崩溃:          

<head>
<script>
    var list = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1];
    var listOrdered = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
    var loopCount = 0;

    while (list !== listOrdered) {
        if (list[loopCount] > list[loopCount + 1]) {
            var lower = list[loopCount + 1];
            var higher = list[loopCount];
            list[loopCount] = lower;
            list[loopCount + 1] = higher;
        }
        if (loopCount === 19) {
            loopCount = 0;
        } else {
            loopCount = loopCount + 1;
        }
    }
</script>
</head>

</html>

我该怎样做才能稳定它?

据我所知,逻辑与我的意图一样正确。 这纯粹是一种娱乐性的实验。

经过进一步发展,比较问题不再存在:

<!doctype html>
<html>
<head>
    <script>
    var sweeps = 0;
    var swaps = 0;
    var list = [25, 21, 4, 23, 32, 2, 40, 8, 27, 9, 29, 33, 31, 14, 12, 16, 35, 18, 37, 20, 39, 19, 38, 17, 36, 15, 34, 13, 6, 11, 30, 10, 28, 7, 26, 5, 1, 3, 22, 24];
    var loop = 0;
    var swapped = 0;
    var ordered = 0;

    while (ordered !== 1) {
        if (list[loop] > list[loop + 1]) {
            var lower = list[loop + 1];
            var higher = list[loop];
            list[loop] = lower;
            list[loop + 1] = higher;
            swapped = 1;
            swaps = swaps + 1;
        }
        if (loop === list.length - 1) {
            if (swapped === 0) {
                ordered = 1;
            }
            swapped = 0;
            loop = 0;
        } else {
            loop = loop + 1;
        }
        sweeps = sweeps + 1;
    }
    alert("list: " + list);
    alert("Sweeps: " + sweeps + ", Swaps: " + swaps);
</script>

(就像“狡猾的怪物”暗示的那样)

2 个答案:

答案 0 :(得分:1)

因为数组对象永远不会是同一个对象,即使它们的内容最终相同(JavaScript在对象(包括数组)上使用比较运算符时不比较值,但它们是否是相同的对象)。您可以将它们序列化为字符串并比较字符串,然后进行适合您的方法的快速比较:

<head>
<script>
var list = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1];
var listOrdered = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
var loopCount = 0;

while (JSON.stringify(list) !== JSON.stringify(listOrdered)) {
    if (list[loopCount] > list[loopCount + 1]) {
        var lower = list[loopCount + 1];
        var higher = list[loopCount];
        list[loopCount] = lower;
        list[loopCount + 1] = higher;
    }
    if (loopCount === 19) {
        loopCount = 0;
    } else {
        loopCount = loopCount + 1;
    }
}
alert(JSON.stringify(list)) // [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
</script></head></html>
默认情况下,

JSON.stringify在旧版浏览器中不可用,因此如果您需要支持旧版浏览器,则可以使用https://github.com/douglascrockford/JSON-js/blob/master/json2.js

答案 1 :(得分:1)

我只是使用一个标志来指示你是否必须在迭代期间交换值,而不是进行比较。如果是,请将计数器重置为0并重置标志。如果没有,你就完成了。

var list = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1];
var loopCount = 0;
var swapped;

while (true) {
    if (list[loopCount] > list[loopCount + 1]) {
        var lower = list[loopCount + 1];
        var higher = list[loopCount];
        list[loopCount] = lower;
        list[loopCount + 1] = higher;
        swapped = true;     // Set the flag indicating we swapped a pair of values.
    }
    if (loopCount === 19) { // At the end of a full iteration...
        if (swapped) {      //  check to see if we had occasion to swap..
            swapped = false;//  and if so, reset the flag, and start again..
            loopCount = 0;
        } else
            break; // or if not, we're done sorting.
    } else {
        loopCount = loopCount + 1;
    }
}

这比任何类型的数组比较都要快得多。