第26题 二叉搜索树与双向链表
题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
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;
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(!pRootOfTree) return nullptr;
Convert(pRootOfTree->right);
if(pre){
pRootOfTree->right = pre;
pre->left = pRootOfTree;
}
pre = pRootOfTree;
Convert(pRootOfTree->left);
return pre;
}
};
思路:
已知二叉搜索树满足左子树小于根节点小于右子树,可以递归进行解决,中序遍历(左->>根->>右)左子树遍历结束后,进行到根节点时,先将根节点的左指针指向左子树,再将左子树的右指针指向根节点,如图:
然后继续进行到右子树,先将右子树的左指针指向根节点,再将根节点的右指针指向右子树,如图:
根据中序遍历的顺序,我们从最小值依序遍历到最大值,最后得到一个有序的双向链表,最后停留在最大值处,若想返回最小值处,可以改变中序遍历顺序(右->>根->>左),先从右子树遍历,最后会停在最小值处,代码如下:
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;
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(!pRootOfTree) return nullptr;
Convert(pRootOfTree->right);
if(pre){
pRootOfTree->right = pre;
pre->left = pRootOfTree;
}
pre = pRootOfTree;
Convert(pRootOfTree->left);
return pre;
}
};
其中我们用pre保存前置遍历节点,采用右子树先行的中序遍历,遇到nullptr直接返回,因为是从大到小遍历,每次处理将当前节点pRootOfTree右指针指向前置节点pre,再将前置节点pre左指针指向pRootOfTree,处理结束后再将前置节点置为现在的节点。