[英]Head pointer doesn't contain child nodes in Binary Tree
我正在復制一棵二叉樹,但我遇到了一個問題,即新樹的根指針最終只包含要復制的第一個節點,而沒有其他節點。 我相信這個問題與這樣一個事實有關,即當我在輔助函數的遞歸中傳遞指針時,由於某種原因,它們沒有被重新分配給新節點的內存地址。 就像在helper(t1->left, t2->left)
t2->left 中一樣,實際上並沒有最終成為我想要的值,它保持為空。
bool first_time = true;
TreeNode* ref = NULL;
void helper(TreeNode* t1, TreeNode* t2) {
if(t1) {
t2 = new TreeNode(t1->val);
if(first_time) {
ref = t2;
first_time = false;
}
helper(t1->left, t2->left);
helper(t1->right, t2->right);
}
}
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
TreeNode* tree1 = new TreeNode(1);
tree1->left = new TreeNode(2);
tree1->right = new TreeNode(3);
helper(tree1, NULL);
return ref;
}
檢查您的全局變量first_time
和ref
。
if (first_time) {
ref = t2; // global
first_time = false; // global set to never go here again
}
它實際上是您問題的根源 - 一旦您將第一個節點傳遞給您的函數,您就更改了其他全局變量ref
並且此后永遠不會在任何地方更改它。 因此,基本上,在每次遞歸調用中,您都會使用懸空指針泄漏內存。 可能,您應該將參數first_time
傳遞給您的函數,並且可能將ref
作為參數傳遞為可分配的
你在這里有幾個問題。
首先, ref
和first_time
是嚴重的缺陷,您應該避免編寫具有這種全局狀態的代碼。 它不是可重入的,也不是線程安全的。
其次,您嘗試寫入 t2 指針並將調用者的指針更改為該值。 但是,您傳入的是 t2 的副本,因此寫入的內容將丟失。
清理它不需要太多,只需更改您的函數以獲取對指針的引用,並且對 t2 的寫入將持續返回給調用者。 請注意,t2 是一個“out”參數,因此初始調用者將通過此指針獲取返回的樹副本。
這是一個固定版本:
void helper(TreeNode* t1, TreeNode*& t2) {
if(t1) {
t2 = new TreeNode(t1->val);
helper(t1->left, t2->left);
helper(t1->right, t2->right);
}
}
這是您的測試函數的樣子:
TreeNode* copyTest() {
TreeNode* tree1 = new TreeNode(1);
tree1->left = new TreeNode(2);
tree1->right = new TreeNode(3);
TreeNode* tree2 = nullptr;
helper(tree1, tree2); // tree2 is written to as new root.
return tree2;
}
但是如果不需要 out 參數,通常不鼓勵使用。
為什么不編寫 copyTree 函數來返回指向復制樹的指針? 基本上去掉in的第二個參數,並分配當前樹的副本,向下遞歸,將每個子副本附加到當前節點的父副本,並返回父節點:
TreeNode* copyTree(TreeNode* tree) {
TreeNode* ret = nullptr;
if (tree) {
ret = new TreeNode(tree->val);
ret->left = copyTree(tree->left);
ret->right = copyTree(tree->right);
}
return ret;
}
除非您非常小心,否則這不是防止泄漏的好方法,但它有助於理解遞歸和樹結構。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.