В вашей реализации вы перемещаетесь по ->
, а затем работаете <-
, что похоже на Right Fold
.
Если вы рассматриваете List как стек вызовов, у вас есть f (f (f (f (...)))) где вы выполняете самый внутренний f первым.Это противоположно хвостовой рекурсии.
То, что вы хотите сделать, это развернуть один слой, создать результат и выполнить рекурсию, используя оставшуюся часть списка.
Делая это слева направо, вашФункция sortHelper, вероятно, должна принимать текущую рабочую версию списка, а в качестве другого аргумента - отсортированную версию.Затем вы можете восстановить один элемент из рабочего списка и поместить его в отсортированный список.Если вы столкнетесь с ситуацией, когда ваш текущий элемент меньше заголовка отсортированного списка, вам следует вернуться в исходное состояние и поместить отсортированную головку обратно в рабочий список, а затем снова поместить головку в список (посколькуНе знаю, столкнетесь ли вы снова с этой ситуацией, когда будете повторяться).
Это многословный вариант ответа, который даст вам возможность попробовать код самостоятельно.
Я включил приведенный ниже код, не смотрите, хотите ли вы попробовать его сами:
import scala.annotation.tailrec
sealed trait MyList[+A] extends Product with Serializable {
val isEmpty: Boolean
def head: A
def tail: MyList[A]
def sort(isLess: (A, A) => Boolean): MyList[A] = {
@tailrec
def inner(working: MyList[A], sorted: MyList[A] = Empty): MyList[A] = working match {
case Empty => sorted
case Cons(h, t) =>
if (sorted.isEmpty) inner(t, Cons(h, Empty))
else if (isLess(h, sorted.head)) inner(Cons(h, Cons(sorted.head, t)), sorted.tail)
else inner(t, Cons(h, sorted))
}
inner(this)
}
}
case object Empty extends MyList[Nothing] {
val isEmpty = true
def head = throw new NotImplementedError("No head on Empty list")
def tail = throw new NotImplementedError("No tail on Empty list")
}
case class Cons[+A](head: A, tail: MyList[A]) extends MyList[A] {
val isEmpty = false
}
object SortTest extends App {
val listOfInts: MyList[Int] = Cons(1, Cons(2, Cons(3, Cons(4, Empty))))
val isLess: (Int, Int) => Boolean = (x, y) => x < y
println(listOfInts.sort(isLess))
}
Просто для удовольствия, здесь настроено использование класса типов Scala's List и Ordering:
import scala.annotation.tailrec
import scala.Ordering.Implicits._
object SortTest extends App {
def sort[A: Ordering](lst: List[A]): List[A] = {
@tailrec
def inner(working: List[A], sorted: List[A] = Nil): List[A] = working match {
case Nil => sorted
case h :: t =>
val (w, s) = sorted.headOption.fold((t, h :: Nil)){ sh =>
if (h < sh) (h :: sh :: t, sorted.tail)
else (t, h :: sorted)
}
inner(w, s)
}
inner(lst)
}
val listOfInts: List[Int] = 1 :: 2 :: 3 :: 4 :: Nil
println(sort(listOfInts))
}