Algorithm 实现迭代的单堆栈二叉树复制函数
作为一个思想练习,我试图实现一个迭代树(二进制或二进制搜索树)复制函数 我的理解是,这可以通过微不足道的方式实现:Algorithm 实现迭代的单堆栈二叉树复制函数,algorithm,data-structures,binary-tree,binary-search-tree,Algorithm,Data Structures,Binary Tree,Binary Search Tree,作为一个思想练习,我试图实现一个迭代树(二进制或二进制搜索树)复制函数 我的理解是,这可以通过微不足道的方式实现: 单叠 不使用包装器(包含对副本和原始节点的引用) 如果节点没有对其父节点的引用(节点中的父节点引用是否与树的真实定义(我认为是DAG)相反?) 我已经编写了不同的实现来满足上述约束的相反要求,但是我不确定如何利用这些约束来解决问题 我没有在算法4/e中看到任何东西,也没有在网上看到任何东西(除了关于它是多么微不足道的声明)。我考虑过使用当前/以前var的顺序和顺序后的概念,但在
- 单叠
- 不使用包装器(包含对副本和原始节点的引用)
- 如果节点没有对其父节点的引用(节点中的父节点引用是否与树的真实定义(我认为是DAG)相反?)
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;
};
模板
结构节点;
typedef节点树\ u节点;
typedef std::shared_ptr shared_ptr_节点;
模板
结构节点最终{
公众:
常数T值;
const shared_ptr_node&left=m_left;
const shared_ptr_node&right=m_right;
节点(const T value,const shared_ptr_Node left=nullptr,const shared_ptr_Node right=nullptr):值(value),m_left(left),m_right(right){
void updateLeft(常量共享\u ptr\u节点){
m_左=节点;
}
void updateRight(常量共享\u ptr\u节点){
m_right=节点;
}
私人:
共享节点m_左;
共享ptr_节点m_权限;
};
然后是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;
}
shared_ptr_节点迭代copy2stack(const shared_ptr_节点和节点){
const shared\u ptr\u node newRoot=std::make\u shared(node->value);
std::堆栈s;
s、 推送(节点);
std::堆栈副本;
copyS.push(newRoot);
共享_ptr_node original=nullptr;
共享\u ptr\u节点副本=空ptr;
而(!s.empty()){
原始=s.顶部();
s、 pop();
copy=copyS.top();
copyS.pop();
如果(原始->右侧){
s、 推送(原始->右侧);
复制->更新权利(标准::使共享(原始->权利->价值));
复制。推送(复制->右);
}
如果(原始->左){
s、 推送(原稿->左);
复制->更新(标准::使_共享(原始->左->值));
复制。推送(复制->左);
}
}
返回newRoot;
}
<>我不精通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):
编辑:
如果您想查看工作代码,我已经在python中创建了一个。您能告诉我们您尝试了什么吗?您有复制函数的递归版本吗?如果是,请在问题中包括它。在第二种情况下,“包装器”的确切含义是什么?我们允许在堆栈中存储什么类型的信息?请注意,a不是。说“树(B或BST)”是。。。有点不稳定。你是说“二叉树还是二叉搜索树?”谢谢你的浅显复制思想,也谢谢你的伪代码和实代码的额外步骤。@GoodEgg很乐意帮忙;)。既然你是新来的:如果这个答案解决了你的问题,考虑一下。谢谢。对于我最初的问题,我有几个答复,所以我将等待一段时间来接受答案-但是考虑到数据结构的限制,我相信您建议的方法是正确的。
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))