根据MDN 规范,Javascript 的 sort() 函数是“不稳定的”(不维护相同元素的输入顺序)。
具有讽刺意味的是,Firefox 目前似乎没有实现这一点——但 Chrome 似乎做到了。
这给我留下了一个问题。我有一组元素要排序 - 一旦排序,我想将它们标记为“已排序”,以便后续的排序尝试不会浪费大量时间发现它们已经排序(如果有任何变化,我可以取消标记它们) .
问题是,我的解决方案是在比较函数中返回“0”,但这意味着我只是为每个元素返回“等价”,它们可以(并且将会)被打乱。
这说明了问题(在这里小提琴)
<head>
<script>
var firsttime=true;
function test() {
debugger;
var elements = document.getElementById('test').children;
var sortMe = [];
for (var i=0; i<elements.length; i++)
sortMe.push(elements[i]);
sortMe.sort(function(a, b) {
if (firsttime) {
if (a.innerText < b.innerText) return -1;
else if (a.innerText > b.innerText) return 1;
else return 0;
} else {
return 0;
}
});
var parent = document.getElementById('test');
parent.innerHTML = "";
for(var i = 0, l = sortMe.length; i < l; i++) {
parent.appendChild(sortMe[i]);
}
firsttime=false;
}
</script>
</head>
<body>
<div id=test>
<div>B</div>
<div>D</div>
<div>A</div>
<div>C</div>
<div>E</div>
<div>B</div>
<div>D</div>
<div>A</div>
<div>C</div>
<div>E</div>
<div>B</div>
<div>D</div>
<div>A</div>
<div>C</div>
<div>E</div>
</div>
<input type=button onclick=test()>
</body>
在 Chrome 上运行,您会看到该集合的中间元素在随后的排序中移动 - 这不会发生在 Mozilla 上(至少不是我这里的版本)。
关于如何解决这个问题而不必每次都求助的任何想法?实际的排序要复杂得多,要检查 100 多个元素,所以需要很多时间,我不想不必要地重复?
编辑添加:我什至尝试使用数组索引强制按顺序对数组进行排序,但即使这在 Chrome 上也不起作用。Chrome 似乎使用了Quicksort的一种变体,它“只是为了它的地狱”交换数组中的元素
似乎我别无选择,只能每次都求助,完全跳过排序或实现我自己的算法......