输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
二叉搜索树按中序遍历有序,因此我们只需按照中序遍历的顺序修改指向,但是如何知道left该指向的前一个节点了,所以我们需要一个指针pre在遍历时保存前一个结点。
pre赋初值为nullptr
若pre不为nullptr,所以pre为当前根节点中序的前一个结点,修改指向即可。
当遍历到最左节点时,此时pre==nullptr,则只需要将当前根赋给pre就行
,因为最左节点的left指向为nullptr,right指向其父节点必然是遍历的下一个结点,因此无需修改指向。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode* pre=nullptr; //pre用来保存遍历时的前一个结点,方便修改指针指向
TreeNode* head=nullptr; //由于采用中序遍历,走到的最后一个节点为最大结点,
//所以需要该节点来保存链表的头
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==nullptr)
return nullptr;
//左
Convert(pRootOfTree->left);
//走到最左边即为最小结点,即链表头结点
if(nullptr==head)
head=pRootOfTree;
//若不为空则表示当前pre结点不是最左节点,而是当前遍历到的根节点的前一个结点
//修改指向
if(nullptr!=pre){
pRootOfTree->left=pre;
pre->right=pRootOfTree;
}
//注意这里如果放在if上边则会造成直接过滤掉pre为空的情况
//记录当前结点,方便下次修改指向
pre=pRootOfTree;
//右
Convert(pRootOfTree->right);
//返回链表头
return head;
}
};