[英]How does recursion work in Haskell? - Example merge function
如果我們看一下合並的函數定義
merge (x:xs) (y:ys) | x <= y = x:merge xs (y:ys)
| otherwise = y:merge (x:xs) ys
輸入 [2,3] [4,1]
第一步看起來像這樣
2<=4 => 2:merge [3] (1:[4])
我的問題在於:第二個列表的第一個頭元素是 4,但是由於 2<=4 沒有對 4 做任何事情,所以 4 必須仍在第二個列表中,但 4 現在必須是列表中的最后一個元素所以可以將 3 與 1 進行比較。我想知道編譯器如何更改第二個列表:起初 4 是 head 元素,但由於再次將 3 與 4 進行比較沒有意義,因此必須切換索引。
那么編譯器只是在第一次比較之后將頭元素放在列表的末尾嗎? 或者編譯器在這里做什么?
我想知道編譯器如何更改第二個列表。
它不是。 如果我們調用merge [2,3] [4,1]
那么您描述的子句將觸發,其中: x = 2
, y = 4
, xs = [3]
和ys = [1]
。 它確實會檢查2 <= 4
是否成立,然后調用合並:
x : merge xs (y:ys)
所以這意味着如果我們使用剛剛分配的變量,我們會得到:
2 : merge [3] (4:[1])
或更簡潔:
2 : merge [3] [4,1]
我想知道編譯器如何更改第二個列表:起初 4 是 head 元素,但由於再次比較 3 和 4 沒有意義,因此必須切換索引。
這種merge
function 通常有一個前提條件,即它旨在合並的兩個列表已經單獨排序。 所以通常不會用MergeSort之類的算法調用merge [2,3] [4,1]
,首先對兩個列表進行排序,然后再使用merge [2,3] [1,4]
調用它。
在將3
與4
進行比較之前,不會將 3 與1
進行比較; merge
保留單個列表中每個值的相對順序。
遞歸進行如下:
merge [2,3] [4,1] == 2 : merge [3] [4,1] -- 2 < 4
== 2 : 3 : merge [] [4, 1] -- 3 < 4
== 2 : 3 : [4, 1] -- assuming merge [] ys == ys
不要將merge
與使用merge
作為子例程的mergeSort
混淆。
mergeSort [] = []
mergeSort xs = merge (mergeSort first) (mergeSort second)
where (first, second) = split xs
split xs = ... -- some function to split a list roughly in half
mergeSort
merge
成為一種穩定的排序算法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.