optimization - 使用 Prolog 在线性时间内展平树
问题描述
我正在尝试优化 Prolog 中树数据结构的扁平化。我能够实现简单的解决方案来按顺序遍历列表,如下所示:
naive_flatten_tree(leaf(X), [X]).
naive_flatten_tree(tree(Left, Val, Right), Flattened_Tree) :-
naive_flatten_tree(Left, LFlat),
naive_flatten_tree(Right, RFlat),
append(LFlat, [Val|RFlat], Flattened_Tree).
直截了当。如果是叶子,则返回它,如果不是在左右子树上递归。将左、右和根值附加在一起,就得到了扁平树。还值得注意的是,叶子在树的定义中明确说明。一个示例树是 Tree(leaf(2), 1, leaf(3))。所以树看起来像
1
/ \
2 3
我需要优化它以线性时间运行到树的大小。描述说这可以使用一个累加器和一个辅助过程来完成,在这个过程中你传入一个空的累加器。还指出您以相反的顺序构建树的展平,然后在辅助过程完成后反转列表。
编辑:
你是这个意思吗?骨架代码:
flatten_tree(tree(Left, Val, Right), Final):-
flatten_tree(Tree, Flat, []).
flatten_tree(Tree, FlatHead, FlatTail):-
然后从这里我一一添加到 FlatTail 因为那是累加器?
解决方案
正如 GuyCoder 所建议的,遵循 DCG 解决方案:
% 1
% / \
% 2 3
% / \ \
% 4 5 6
example(tree(tree(leaf(4),2,leaf(5)),1,tree(nil,3,leaf(6)))).
% inorder(+Tree, -List)
inorder(Tree, List) :- phrase(ft(Tree), List, []).
ft(nil) --> [].
ft(leaf(V)) --> [V].
ft(tree(L,V,R)) --> ft(L), [V], ft(R).
例子:
?- example(T), inorder(T, L).
T = tree(tree(leaf(4), 2, leaf(5)), 1, tree(nil, 3, leaf(6))),
L = [4, 2, 5, 1, 3, 6].
?- inorder(nil, L).
L = [].
?- inorder(leaf(1), L).
L = [1].
?- inorder(tree(leaf(1),2,leaf(3)), L).
L = [1, 2, 3].
?- inorder(tree(leaf(1),2,nil), L).
L = [1, 2].
?- inorder(tree(nil,2,leaf(3)), L).
L = [2, 3].
推荐阅读
- javascript - 添加动态数据时,Bootstrap 轮播不会滑动
- google-maps - 将从 github 下载的库安装到 vue 项目中,而不仅仅是使用 npm
- php - 如何更改输入类型日期 HTML5 的默认占位符
- java - 为什么我的 Yarn 应用程序没有从 Windows 转移到 Hortoworks 沙箱?
- c - 在 FreeRTOS 第一次任务运行期间,第二个固件插槽跳转到第一个插槽
- angular - 将类应用于 ngFor 循环中的 html 元素
- c++ - std::async 究竟是如何执行的?
- ios - ios - 在导航项栏中切换
- python - 如何将seaborn boxplot胡须基于百分位数?
- ruby-on-rails - 按集合中的列对多个条目进行分组