我正在读一本名为“算法简介”的书。我想很多人都知道。我刚刚碰到了一个看似相当困难的问题:
写一个O(n)-time非递归过程,给定一个n节点二叉树, 打印出每个节点的密钥。在树本身之外使用不超过恒定的额外空间,并且在此过程中不要修改树,即使是暂时的。
我看到还有另外一个问题:How to traverse a binary tree in O(n) time without extra memory但主要区别在于我无法修改树。我正在考虑使用一些访问过的标志,但我还没有提出正确的解决方案。这可能是我看不到的明显的东西。你会如何设计一个解决这个问题的算法?即使是对答案的一些指示也会受到赞赏。
答案 0 :(得分:7)
如果树是双向链接的,您可以这样做:
assert root.parent is null
now, old = root, null
while now != null:
print now.label
if leaf(now):
now, old = now.parent, now
else:
if old == now.right:
now, old = now.parent, now
if old == now.left:
now, old = now.right, now
if old == now.parent:
now, old = now.left, now
以root,left,right顺序打印,但您可以获得任何您喜欢的订单。
如果树仅在一个方向上链接,我认为你不能这样做。您可以查看Deforestation。
答案 1 :(得分:0)
有完整的代码(在Ruby中)。
作为一个例子,我已经复制了相同的" n节点二叉树"如"算法简介" 一书。
class Node
attr_accessor :key, :parent, :left, :right
def initialize(key, parent)
@key = key
@parent = parent
end
end
class Tree
def initialize(root)
@root = root
end
def print_with_constant_space
current, old = @root, nil
while current do
# Going UP
if old && old.parent == current
# Go right if exists
# otherwise continue up
next_node = (current.right || current.parent)
current, old = next_node, current
# Going DOWN
else
puts current.key
# Go left if exists
# otherwise go right if exists
# otherwise go up
next_node = (current.left || current.right || current.parent)
current, old = next_node, current
end
end
end
end
root = Node.new(0, nil)
root.left = (node_1 = Node.new(1, root))
node_1.left = (node_2 = Node.new(2, node_1))
node_2.right = (node_3 = Node.new(3, node_1))
node_3.left = (node_4 = Node.new(4, node_3))
node_1.right = (node_5 = Node.new(5, root))
node_5.left = (node_6 = Node.new(6, node_5))
node_6.right = (node_7 = Node.new(7, node_5))
node_7.right = (node_8 = Node.new(8, node_5))
node_8.left = (node_9 = Node.new(9, node_8))
node_9.right = (node_10 = Node.new(10, node_8))
node_8.right = (node_11 = Node.new(11, node_5))
node_5.right = (node_12 = Node.new(12, root))
node_12.left = (node_13 = Node.new(13, node_12))
tree = Tree.new(root)
tree.print_with_constant_space
我希望它有所帮助...
答案 2 :(得分:0)
您必须对树进行有序行走。在同一本书中,关于二元搜索树的章节的第一组练习中有一个提示。引用:
有一个简单的解决方案,它使用堆栈作为辅助数据结构和更复杂但更优雅的解决方案,它不使用堆栈,但假设可以测试两个指针的相等性。
您可以在此处找到实施:http://tech.technoflirt.com/2011/03/04/non-recursive-tree-traversal-in-on-using-constant-space/