|
|
1
10
作为
starblue already said
,需要一个函数来计算列表的最小值,并返回删除该元素的列表。下面是类似的递归实现(我相信
这基本上是一个折叠,从包含
创建这个助手函数之后,现在很容易实现选择排序。
不幸的是,这个实现是 不 尾部递归,因此它将放大大列表的堆栈。无论如何,您不应该对大列表使用o(n^2)排序,但是…如果实现是尾部递归的,那就更好了。我会想办法…我认为它会像一个折叠的实现。 尾部递归!
为了使其尾部递归,我在函数编程中使用了非常常见的模式——一个累加器。它有点向后工作,因为现在我需要一个名为
编辑 :更改了答案,使助手函数作为选择排序函数的子函数。
它基本上将极大值累积到一个列表中,最终作为基本情况返回。您还可以通过替换看到它是尾部递归的
这里有一个使用累加器的逐步排序。左侧显示列表
以下显示了逐步折叠以计算最大值:
|
|
|
2
2
这里是选择排序(通用版本)的另一个实现。
|
|
|
3
1
您需要一个辅助函数来进行选择。它应该返回最小元素和列表中删除元素后的其余部分。 |
|
|
4
1
在函数样式中进行选择排序时应该会遇到问题,因为它是一种就地排序算法。根据定义,就地不起作用。 你面临的主要问题是你不能 掉期 元素。这就是为什么这一点很重要。假设我有一个清单 0 …一 X …一 n ,在哪里 X 是最小值。你需要一个 X 离开,然后组成一个列表(a 零 ……一 X-1 一 X+ 1 一 n )问题是你必须 复制 元素A 零 到A X-1 ,如果您希望保持纯粹的功能性。其他的功能数据结构,特别是树,可以有比这更好的性能,但基本的问题仍然存在。 |
|
|
5
1
我认为以功能性风格进行选择是合理可行的,但是正如丹尼尔所指出的,它有很好的机会表现得很糟糕。 我只是试着写一个函数气泡排序,作为一个稍微简单和退化的选择排序案例。以下是我所做的,这暗示了你可以做什么:
一旦完成递归,最大的元素就在列表的末尾。现在,
完成后,您的数据确实会被排序。是的,这很可怕,但是我对这个伪代码的Clojure实现是有效的。 仅仅关注第一个或两个元素,然后将其余的工作留给一个重复的活动,这是一种lisp-y、功能性y的方法来完成这类事情。但是一旦你的头脑习惯了这种想法,就有了更明智的方法来解决这个问题。 我建议实现合并排序:
递归就是其中的一部分,我看不出一种巧妙的方法可以使算法尾部递归。不过,我认为这是O(log-2)的时间,也不会给堆栈带来过高的负载。 玩得开心,祝你好运! |
|
|
6
1
感谢上面的提示,他们非常鼓舞人心。这是选择排序算法的另一种功能方法。我试着基于以下想法:找到一个最大/最小值可以很容易地通过
(这是尾部递归) 现在需要一个Min版本,它返回一个不包含Min值的列表。以下函数返回一个列表,其头部是最小值,尾部包含原始列表的其余部分:
使用此选择排序可以以递归方式编写尾部,如下所示:
(颠倒顺序)。在一个包含10000个列表元素的测试中,该算法仅比通常的命令式算法慢4倍。 |
|
|
7
1
尽管,在编写scala时,我习惯于使用函数式编程(通过组合器或递归)而不是命令式编程(通过变量和迭代),但这次,对于这个特定的问题,老式的命令式嵌套循环会导致更简单和更高性能的代码。 我不认为退回命令式对于某些问题是一个错误,例如排序算法,它通常将输入缓冲区转换到位,而不是生成一个新的集合。 我的解决方案是:
如您所见,实现参数多态性,而不是使用
您可以编写如下客户端程序:
|
|
|
8
1
scala中选择排序的简单函数程序
|
|
9
0
您可能想尝试用递归替换while循环,所以有两个地方可以创建新的递归函数。 这将开始消除一些var。 这对我来说可能是最艰难的一课,我试图向外交政策迈进。 我不愿意在这里展示解决方案,因为我认为你最好先试试。 但是,如果可能的话,您应该使用尾部递归,以避免堆栈溢出的问题(如果您正在排序一个非常非常大的列表)。 |
|
|
10
0
以下是我对这个问题的看法: SelectionSort.scala
有两个内部功能:
这是scala中选择排序的100%功能实现。 |