带有尾递归的scala中的递归排序

时间:2014-01-14 05:25:55

标签: scala sorting recursion tail-recursion

我正在尝试用Scala中的尾递归编写这个算法。

public ArrayList sort(ArrayList<int> toSort)
{
  ArrayList<int> list=toSort;
      for(int i=0; i<list.size();i++)
      {    int min=100;
           int pos=-1;
           for(int j=i+1; j<list.size();j++)
           {
                if(list.get(i)>list.get(j) && list.get(j)<min)
                {
                    min=list.get(j);
                    pos=j;
                }
           }
           if(pos!=-1)
           {
                int a=list.get(i);
                list.set(i,list.get(pos));
                list.set(pos,a);
           }
      }
    return list;
}

我是Scala和函数式编程的新手,所以我不太清楚如何编写代码。 任何人都能帮助我一些想法吗?

非常感谢您提前

3 个答案:

答案 0 :(得分:2)

这是Scala中“是”的代码,尽管它是我写过的最糟糕的Scala代码。我希望将它1:1保存到您的代码中。但我希望它的目的是演示如何编写尾递归。没什么,没什么。

def sort(toSort: util.ArrayList[Int]): util.ArrayList[Int] = {
  val list = toSort

  @tailrec
  def outerLoop(i: Int) {

    if (i < list.size) {
      var min = 100
      var pos = -1

      @tailrec
      def innerLoop(j: Int) {
        if (j < list.size) {
          if (list.get(i) > list.get(j) && list.get(j) < min) {
            min = list.get(j)
            pos = j
          }

          innerLoop(j + 1)
        }
      }

      if (pos != -1) {
        val a = list.get(i)
        list.set(i, list.get(pos))
        list.set(pos, a)
      }

      outerLoop(i + 1)
    }
  }

  outerRec(0)
}

答案 1 :(得分:0)

这是不可变的tailrec解决方案。它并不复杂,我只是正确地将您的代码转换为不可变的方法。

import annotation.tailrec

val list = List(1,4,2,7,6,9,8)

@tailrec
final def inner(min: Int, pos: Int, item: Int, i: Int, list: List[(Int, Int)]): Map[Int, Int] = list match {
  case (pItem, p) :: tail if(item > pItem &&  pItem < min) => inner(pItem, p, item, i, tail)
  case (pItem, p) :: tail => inner(min, pos, item, i, tail)
  case Nil if(pos != -1) => Map(i -> min, pos -> item)
  case Nil => Map.empty[Int, Int]
}

@tailrec
final def outer(list: List[(Int, Int)], acc: Map[Int, Int] = Map.empty[Int, Int]): Map[Int, Int] = list match {
  case (item, i) :: tail => outer(tail, acc ++ inner(100, -1, item, i, tail))
  case Nil => acc
}

def tailSort(list: List[Int]) = {
  val zipped = list.zipWithIndex
  outer(zipped, zipped.map(_.swap).toMap).toList.sortBy(_._1).map(_._2)
}

tailSort(list)

res41: List[Int] = List(1, 2, 4, 6, 7, 8, 9)

答案 2 :(得分:0)

您可以为此使用延续传递样式。

val sort: List[Int] => List[Int] = {
  @tailrec def ins(n: Int, l: List[Int], acc: List[Int]): List[Int] = l match {
    case Nil => (n :: acc).reverse
    case x :: xs => if (n < x) acc.reverse ++ (n :: l) else ins(n, xs, x :: acc)
  }

  @tailrec def sort1[A](l: List[Int], k: List[Int] => A): A = l match {
    case Nil => k(Nil)
    case x :: xs => sort1(xs, l => k(ins(x, l, Nil)))
  }

  l => sort1(l, x => x)
}