故事起因来自于在leetcode写一个有关于二叉树的题目,题中需要涉及到树节点的交换,这里就牵扯到了swap函数,我在使用C++和Java实现题目求解的过程中,就出现了一些小问题,有关于值传递和应用传递的问题,我都明白其原理,但是在实际写程序的过程中还是会出现问题,所以在此写下笔记。(下面这篇笔记写得很好)
C++swap详解:https://blog.csdn.net/apollon_krj/article/details/51445885
Java到底实现的是值传递还是引用传递? 请看看下面博文
https://blog.csdn.net/singwhatiwanna/article/details/105671887?spm=1001.2014.3001.5502
这个题目用C++来写的话,其自带的标准库中自带swap交换函数,所以可以直接使用,代码试下如下:
class Solution {
public:
//C++的STL中自带了swap()
TreeNode* invertTree(TreeNode* root) {
if(root == NULL) return root;
swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);
return root;
}
};
我出于夯实知识的目的,所以自己实现了一次swap函数,但是我发现自己的C相关的基础知识真的忘记太多了,连函数头中传入的类型都写错,后面几番修改才得到正确的答案。因为我们是要实现引用传递,所以我们要传入TreeNode类型指针的引用地址,所以一定要加上&(取地址符号),如下所示: swap(TreeNode* &left, TreeNode* &right)
class Solution {
public:
//这里要传地址,不能传值
void swap(TreeNode* &left, TreeNode* &right){
TreeNode* temp = left;
left = right;
right = temp;
}
//C++的STL中自带了swap()
TreeNode* invertTree(TreeNode* root) {
if(root == NULL) return root;
swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);
return root;
}
};
Java中并没有自带swap函数,所以需要自己实现,但是我一开始模仿着上面C++代码的实现,出现了问题。有问题的代码如下:
//Java的swap函数
//这个题目的swap函数如果下面这样写的话的是错误的
public void swap(TreeNode node1, TreeNode node2){
TreeNode temp = node1;
node1 = node2;
node2 = temp;
}
//后序遍历
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
invertTree(root.left);
invertTree(root.right);
swap(root.left,root.right);
return root;
}
现在仔细看看上面的代码是真的好笑,完全是照猫画虎,swap函数并没有实现树中两个节点的交换,(C++中的swap函数用了&取地址,所以应用传值能够实际修改到树中的两个节点)。后面,经过几番摸索,终于整出了正确交换两个树节点的swap函数:
//正确解答的方法是:
//请注意这里swap函数如何书写(这里swap函数和C++里传入左右两个孩子节点不一样)
public void swap(TreeNode root){
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
//后序遍历
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
invertTree(root.left);
invertTree(root.right);
swap(root);
return root;
}
语言的差异带来实现上的差异是必然存在的,所以请好好对比两个实现的差异,而不是一昧的照搬。