此处感谢:http://blog.csdn.net/ljb825802164/article/details/50540777
1. 题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
2. 题目分析
二叉搜索树的性质:左子树小于根节点,右子树大于根节点。所以,将二叉搜索树转换成一个排序的双向列表,即从头至尾的顺序为:左子树、根节点、右子树。
但是要特别注意的是,在双向链表中,第一个元素也是有指向前一个元素的指针的,只不过是nullptr,所以在转换时不要忘记该节点的指针。同样最后一个元素也有指向后节点的指针的,同样是nullptr。
3. 题目解答——cpp
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if (pRootOfTree == nullptr){
return NULL;
}
TreeNode* prepoint = nullptr;
helpConvert(pRootOfTree,prepoint);
while(pRootOfTree->left!=nullptr){
pRootOfTree = pRootOfTree->left;
}
return pRootOfTree;
}
// 注意此处的prepoint的传参方式
void helpConvert(TreeNode* pRootOfTree, TreeNode*& prepoint){
if (pRootOfTree == nullptr){
return;
}
helpConvert(pRootOfTree->left,prepoint);
pRootOfTree->left = prepoint;
if(prepoint != nullptr){
prepoint->right = pRootOfTree;
}
prepoint = pRootOfTree;
helpConvert(pRootOfTree->right,prepoint);
}
};
4. 注意点解析
在此处应该尤其注意辅助函数helpConvert的传参方式,prepoint参数传递时,使用的是引用传递的方式。原因如下:
1)指针虽然是地址传递,但实际上也是在函数中又定义了一个新的指针让其与传入的指针指向同一地址。但两个指针本身作为变量在内存中的存放地址是不同的,就是说这是两个不同的变量,只是内容(即所指地址)相同。
2)在函数中对新定义的指针动态申请内存,但是当函数结束后,申请的内存的生命周期也就结束了,所以当回到主函数时,作为实参的指针地址和内容都没有变化。仍然是个空指针,对其进行访问自然出现了内存读错误了。
假如在main函数中这样写:
int *a = (int*)malloc(sizeof(int)*3);
就不会出现内存读错误了,但是输出结果还是错误的,道理也是一样的。
3)用引用作为实参传入时,fun函数中的b其实就是主函数中a的别名(或者叫外号),反正就是操作完全相同,地址相同,内容相同的一个变量,所以当fun函数返回时,对b的操作在主函数中对a同样有效。