【问题标题】:Why doesn't my selection sort code work when there are duplicate numbers?当有重复的数字时,为什么我的选择排序代码不起作用?
【发布时间】:2019-05-25 01:19:17
【问题描述】:

我已经使用具有非重复值的数组测试了我的代码,它似乎工作正常。当我确实有重复时,它不起作用。

这是我目前所拥有的。我认为找到切片数组最小值的代码行给我带来了问题。

function selectionSort(array) {
 
    for (let i = 0; i < array.length; i++) {

        let min = Math.min(...array.slice(i));
        let indexMin = array.indexOf(min)
        array.splice(indexMin, 1)
        array.splice(i,0,min);
    }
    return array;
}

console.log(selectionSort([3, 0, -5, -5]));

使用[3,0,-5,-5]的测试数组,在循环的第一次迭代中,最小值为-5,indexMin为2。拼接数组后,我得到[3, 0,-5]。当我再次拼接它(在数组的开头插入值)时,我得到了预期的 [-5,3,0,-5] 。在第二次迭代中,我希望最小值是索引 3 处的 -5 ......但是当我控制台记录最小值时,它说它是索引 0 处的 -5。我指定我想从中找到最小值(...array.slice(1)),那么为什么在索引 0 处将 min 设置为 -5?

【问题讨论】:

  • "我指定我想从 (...array.slice(1)) 中找到最小值" - 是的,但您还指定了要查找该元素在整个数组中的索引:array.indexOf(min)(包括已经排序的部分)。
  • indexOf 也将fromIndex 作为第二个参数 - 试试array.indexOf(min, i)
  • 你不应该使用splice,你应该简单地交换两个元素。数组不是列表,splice 操作并不便宜(尽管它对复杂性无关紧要,选择排序无论如何都是O(n²)

标签: javascript selection-sort


【解决方案1】:

问题在于,当您有重复时,indexOf 返回第一个的索引,这不是您在看过一次后完成它后想要的 -– 它总是找到第一个匹配项,即使当有多个时。

indexOf() 采用可选的第二个参数来指示从何处开始搜索。您可以传入 i 以从正确的位置开始跳过已排序的值。

function selectionSort(array) {
  for (let i = 0; i < array.length; i++) {
    let min = Math.min(...array.slice(i));
    let indexMin = array.indexOf(min, i); // pass in i
    [array[indexMin], array[i]] = [array[i], array[indexMin]]
  }
  return array;
}

console.log(selectionSort([4, 5, 4, 3, 3, 3, 1, 3, 1]))

【讨论】:

  • lastIndexOf 将给出数组中最后一个匹配元素的索引 - indexOf(min, i) 是这里需要的
  • 你可以用[array[i], array[indexMin]] = [array[indexMin], array[i]]; 替换两个拼接,假设你用分号结束前一行(你目前不这样做)。
  • 我同意@PatrickRoberts,只是在考虑眼前的问题。但是splices 没有任何意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
相关资源
最近更新 更多