简体   繁体   English

如何在Scala中实现插入排序?

[英]How to implement Insertion Sort in Scala?

I have the following code given in Scala: 我在Scala中给出了以下代码:

def insertsort (l: List[Int]): List[Int] = {
        if (l == Nil) Nil
        else insert (l.head, insertsort (l.tail))
}

How do I implement insert() now? 我现在如何实现insert()

Here's how I'd go about insertion sort: 这是我进行插入排序的方法:

def insertSort(l: List[Int]): List[Int] = {
  l.foldLeft(List.empty[Int]) { (sorted, i) =>
    val (less, greater) = sorted.partition(_ < i)
    (less :+ i) ++ greater
  }
}

If you're not familiar with foldLeft, here's how it works. 如果您不熟悉foldLeft,请按以下步骤操作。 When we say l.foldLeft, that means we're going to do something for each member of l, the list we want to sort. 当我们说l.foldLeft时,这意味着我们将为l的每个成员(我们要排序的列表)做一些事情。 We pass in as the first argument an empty list, which represents the portion of the list we have already sorted (which starts empty because we haven't done anything yet). 我们将一个空列表作为第一个参数传入,该空列表表示我们已经排序的列表的一部分(由于我们尚未执行任何操作,所以开始为空)。 For each iteration of the foldLeft, we are going to add one more element of the list in sorted order, and build upon our solution this way. 对于foldLeft的每次迭代,我们将按排序顺序添加列表中的另一个元素,并以此方式构建我们的解决方案。

The second argument is a function with two arguments. 第二个参数是带有两个参数的函数。 The first is the accumulating sorted list, the second is the current integer from l that we are attempting to add into the sorted list. 第一个是累积排序列表,第二个是我们试图添加到排序列表中的l中的当前整数。 We split the sorted list into two lists, one that is less than the current int, and one that is greater than/equal. 我们将排序后的列表分为两个列表,一个列表小于当前int,另一个列表大于/等于。 we then insert our int in the middle. 然后,我们将int插入中间。 The return value of this function becomes the first argument in the next iteration (what we called 'sorted'). 该函数的返回值成为下一次迭代的第一个参数(我们称为“已排序”)。

Let's sort l = List(3, 1, 2) 让我们排序l = List(3,1,2)

1st pass: sorted = Nil, i = 3. less and greater are both Nil. 第一遍:排序= Nil,i =3。越来越少的都是Nil。 the function returns Nil + 3 + Nil, which is List(3), which becomes sorted for the next pass. 该函数返回Nil + 3 + Nil,即List(3),将在下一次传递时进行排序。

2nd pass: sorted = List(3), i = 1. less = Nil, greater = List(3). 第二次通过:已排序= List(3),i =1。更少=无,更大= List(3)。 the function returns Nil + 1 + List(3), which = List(1, 3). 该函数返回Nil +1 + List(3),即= List(1,3)。

3rd pass: sorted = List(1, 3), i = 2. less = List(1), greater = List(3). 第三遍:已排序= List(1,3),i =2。更少= List(1),更大= List(3)。 function returns List(1) + 2 + List(3) = List(1, 2, 3). 函数返回List(1)+ 2 + List(3)= List(1、2、3)。

After we have iterated over all of l, the foldLeft returns the final accumulated value (the value of the last line of the last iteration, in our case: List(1, 2, 3)). 在对所有l进行迭代之后,foldLeft返回最终的累加值(在我们的示例中为上一次迭代的最后一行的值:List(1、2、3))。

Hope that helps! 希望有帮助!

Check this out. 看一下这个。

/**
   * Insertion sort algorithm(https://en.wikipedia.org/wiki/Insertion_sort)
   * typically has nested loops with mutable state in imperative style of program
   *
   * Steps of an insertion sort:
   * 3 7 4 9 5 2 6 1
   * 3 7 4 9 5 2 6 1
   * 3 7 4 9 5 2 6 1
   * 3 4 7 9 5 2 6 1
   * 3 4 7 9 5 2 6 1
   * 3 4 5 7 9 2 6 1
   * 2 3 4 5 7 9 6 1
   * 2 3 4 5 6 7 9 1
   * 1 2 3 4 5 6 7 9
   *
   * @param input
   * @return
   */
  def insertionSort(input: List[Int]): List[Int] = {

    input.foldLeft(List[Int]())( (acc, element) => {

      val (firstHalf, secondHalf) = acc.span(_ < element)

      //inserting the element at the right place
      firstHalf ::: element :: secondHalf
    })
  }

Here is the source code 这是源代码

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

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