题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路
二叉树有左右两个指针;而双向链表也有前后两个指针,该题目是用二叉树的左右指针代替前后指针,完成二叉搜索树到排序双向链表的转换。
二叉搜索树按中序遍历就相当于排序;该题的重点在于遍历的过程中需要同时完成左右指针的转换。
将整个过程分为两步:
(1)将根节点与排好序的左子树的最右节点连接
(2)将根节点与排好序的右子树的最左节点连接
这个过程可以用递归实现。
相当于在已排序的双向链表后加入访问节点,完成前后指针的转换;因为按照中序遍历,所以是从小到达排序的。
代码
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree){
if (pRootOfTree== nullptr)
return pRootOfTree;
TreeNode* lastNodeInList = nullptr; // 保存当前双向链表的尾节点
ConvertNode(pRootOfTree, &lastNodeInList); // 得到转换完后双向链表的尾节点
TreeNode* pHeadofList = lastNodeInList;
pHeadofList->right = nullptr;
while(pHeadofList->left!= nullptr)
pHeadofList = pHeadofList->left;
return pHeadofList;
}
// 左子树的最右节点 -》根节点-》右子树最左节点
// 二叉搜索树按中序遍历:从小到大
void ConvertNode(TreeNode* root, TreeNode** lastNodeInList){
if(root== nullptr)
return;
// 左子树转换
ConvertNode(root->left,lastNodeInList);
root->left = *lastNodeInList; // 根的左指针指向排序完左子树最右节点
if(*lastNodeInList != nullptr)
(*lastNodeInList)->right = root;
// 将根节点加入排序列表;并在右子树中递归
*lastNodeInList = root;
ConvertNode(root->right,lastNodeInList);
}
};