Haskell中foldl为何两次调用列表?冒泡排序代码解析求助
Haskell冒泡排序代码解析:foldl遍历xs的原因
先看你给出的代码:
burbuja xs = foldl (\acc _ -> bsort acc) xs xs
先明确bsort的作用
首先得知道bsort是单次冒泡遍历函数——它会从头遍历列表,两两比较相邻元素并交换位置,把当前未排序部分的最大元素“冒”到列表末尾。比如:
bsort [4,3,2,1]→[3,2,1,4](最大的4移到最后)bsort [3,2,1,4]→[2,1,3,4](次大的3移到倒数第二)
拆解foldl的逻辑
foldl在这里的作用是控制冒泡遍历的次数:
- 第一个参数
(\acc _ -> bsort acc)是累加器函数:每次迭代时,不管当前遍历到xs的哪个元素(用_忽略,因为我们不需要元素值),都把上一次迭代后的列表(acc)传给bsort,得到新的列表作为下一次的累加器。 - 第二个参数
xs是初始累加器值,也就是待排序的原列表。 - 第三个参数
xs是要遍历的列表:foldl会遍历这个列表的每一个元素,每遍历一次就执行一次累加器函数。
为什么用xs作为遍历列表?
冒泡排序的特性是:对于长度为n的列表,最多需要n次单次冒泡遍历,就能确保整个列表完全有序(哪怕中途列表已经有序,多执行几次也不会出错)。
用xs作为遍历列表,刚好能让foldl执行length xs次bsort调用——也就是刚好满足冒泡排序需要的最大遍历次数,保证列表被排好序。
举个具体例子
比如输入xs = [4,3,2,1],foldl会执行4次迭代:
- 初始
acc = [4,3,2,1]→ 调用bsort得到[3,2,1,4] acc = [3,2,1,4]→ 调用bsort得到[2,1,3,4]acc = [2,1,3,4]→ 调用bsort得到[1,2,3,4]acc = [1,2,3,4]→ 调用bsort还是[1,2,3,4]
最终输出就是排序后的列表。
补充说明
你问“为何foldl需要两次遍历xs列表”——其实这里不是两次遍历,而是foldl遍历xs的n个元素(执行n次迭代),每次迭代内部bsort会遍历一次列表,总共是n次列表遍历,这正是冒泡排序的标准流程。
内容的提问来源于stack exchange,提问作者Vladimir Sánchez Martínez
相关产品推荐
相关产品推荐

