簡體   English   中英

遞歸在 Haskell 中如何工作? - 示例合並 function

[英]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 = 2y = 4xs = [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]調用它。

在將34進行比較之前,不會將 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM