作为思考练习,我试图实现迭代树(二进制或二叉搜索树)复制功能。
我的理解是,它可以通过以下方式实现:
我编写了不同的实现来满足上述约束的反转,但我不确定如何使用约束来解决问题。
我没有在算法4 / e中看到任何内容,也没有在网上看到任何东西(超出它的微不足道的陈述)。我考虑使用当前/之前var的顺序和发布顺序的概念,但是在弹出堆栈时我没有看到准确跟踪的方法。我还简要地考虑了哈希映射,但我觉得这仍然只是额外的存储空间。
感谢任何有助于理解我没有看到的方法背后的概念/习语的帮助。
提前致谢。
修改
对我迄今为止尝试过的一些要求。这是2堆栈解决方案,我认为应该能够最简单地转换为1堆栈。
用C ++编写。我是语言新手(但不是编程),并使用C ++ Primer 5 / e(Lippman,Lajole,Moo)[C ++ 11]和互联网自学。如果语言角度的任何代码有误,请告诉我(虽然我知道Code Review Stack Exchange是进行实际审核的地方)。
我有一个模板节点,由代码的其他部分使用。
template<typename T>
struct Node;
typedef Node<std::string> tree_node;
typedef std::shared_ptr<tree_node> shared_ptr_node;
template<typename T>
struct Node final {
public:
const T value;
const shared_ptr_node &left = m_left;
const shared_ptr_node &right = m_right;
Node(const T value, const shared_ptr_node left = nullptr, const shared_ptr_node right = nullptr) : value(value), m_left(left), m_right (right) {}
void updateLeft(const shared_ptr_node node) {
m_left = node;
}
void updateRight(const shared_ptr_node node) {
m_right = node;
}
private:
shared_ptr_node m_left;
shared_ptr_node m_right;
};
然后是2堆栈实现。
shared_ptr_node iterativeCopy2Stacks(const shared_ptr_node &node) {
const shared_ptr_node newRoot = std::make_shared<tree_node>(node->value);
std::stack<const shared_ptr_node> s;
s.push(node);
std::stack<const shared_ptr_node> copyS;
copyS.push(newRoot);
shared_ptr_node original = nullptr;
shared_ptr_node copy = nullptr;
while (!s.empty()) {
original = s.top();
s.pop();
copy = copyS.top();
copyS.pop();
if (original->right) {
s.push(original->right);
copy->updateRight(std::make_shared<tree_node>(original->right->value));
copyS.push(copy->right);
}
if (original->left) {
s.push(original->left);
copy->updateLeft(std::make_shared<tree_node>(original->left->value));
copyS.push(copy->left);
}
}
return newRoot;
}
答案 0 :(得分:1)
我不熟悉c ++,所以你必须解决伪代码问题:
node copy(treenode n):
if n == null
return null
node tmp = clone(n) //no deep clone!!!
stack s
s.push(tmp)
while !s.empty():
node n = s.pop()
if n.left != null:
n.left = clone(n.left)
s.push(n.left)
if n.right != null:
n.right = clone(n.right)
s.push(n.right)
return tmp
请注意,clone(node)
不是深层克隆。基本思想是从根的浅层克隆开始,然后迭代该节点的所有子节点并用浅拷贝替换那些节点(仍然引用原始节点),替换那些节点子节点等。这个算法遍历以DFS方式的树。如果您更喜欢BFS(无论出于何种原因),您只需用队列替换堆栈即可。这段代码的另一个优点是:它可以通过一些小的改动来改变,以适应任意树。
这个算法的递归版本(如果你更喜欢我可怕的prosa上的递归代码):
node copyRec(node n):
if n.left != null:
n.left = clone(n.left)
copyRec(n.left)
if n.right != null:
n.right = clone(n.right)
copyRec(n.right)
return n
node copy(node n):
return copyRec(clone(n))
编辑:
如果你想查看工作代码,我在python中创建了一个implementation。