题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
解析:
这道题一开始看答案都无法理解,后来终于弄懂了
就是将二叉树的left和right转化为链表节点的左右指针,因为是按照从小到大顺序所以就得是中序遍历,得到每个节点,然后就是对节点进行指针运算
这三句是关键,而且前两句顺序不能变
//cur指向当前节点,pre指向前一个节点
cur->left = pre;//将cur->left指向pre,就是向左的方向指针建立连接
if (pre)pre->right = cur;//将pre->right指向cur就是向右的方向指针建立连接
pre = cur;将后一个节点给pre
为什么pre要用引用或者二级指针?
明白这个首先要明白指针的地址和指针指向的地址,指针有自己的地址,而地址上存着值(一般我们改变以及指针指向就是将地址上的值存另一个节点的地址,这样不就是指向这个节点了吗,但是自己指针的地址还是自己地址,只是指针地址上的值变了)(自己博客指针那一栏有转发文章讲了),cur用一级指针就可以了,因为cur指针指向哥哥节点就可以了,然后对当前节点进行操作改变left和right值。但是pre必须要用二级指针或者引用,因为要保存前一个指针的地址,就相当于自己造了一个地址,就是自己弄出来个节点,而pre要跟着cur指针向前走,所以必须是cur指针将地址给他。
为什么cur不用二级指针?
因为cur指向当前节点,就能够操作left和right指针,而pre指针一开始nullptr,他谁也不指向,然后cur给pre就改变了他的指向,那我有问了,那我第一次把pre给cur不就行了,然后指向pre->right不就行了,问题所在就是pre->right没有,这是需要自己弄出来的,所以必须每次cur把地址给他
/*
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)return nullptr;
TreeNode *pre = nullptr;
ConvertTreeNode(pRootOfTree, pre);
TreeNode *res = pRootOfTree;
while (res->left) {
res = res->left;
}
return res;
}
void ConvertTreeNode(TreeNode* cur, TreeNode*& pre)
{
if (cur == nullptr)return;
ConvertTreeNode(cur->left,pre);
cur->left = pre;
if (pre)pre->right = cur;
pre = cur;
ConvertTreeNode(cur->right, pre);
}
};