题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路:
对二叉树进行中序遍历,将中序遍历的节点连接起来,问题时中序遍历时,前一个节点容易丢失,所以要拿一个节点来保存上一个节点,并对这个临时节点进行更新。具体代码如下:
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==NULL) return NULL;
midTranverse(pRootOfTree);
//这一步是为了找到链表的头结点
while(pRootOfTree ->left)
pRootOfTree = pRootOfTree ->left;
return pRootOfTree;
}
private:
TreeNode* pre=NULL;//设置一个前驱节点,用来记忆遍历的时候当前节点的上一个节点
//二叉树中序遍历
void midTranverse(TreeNode* node)
{
if(node==NULL)
{
return;
}
midTranverse(node->left);//递归到最底层时,node是最左侧的叶节点
node->left=pre;//第一次pre是空节点,之后再递归返回时,pre是更新后的节点
if(pre) pre->right=node;//实现双向连接
pre=node;//跟新这个前驱节点,用于连接下一个节点
midTranverse(node->right);
}
};
在这个最后一步,有个问题想跟读者讨论一下,我本来是先找到了二叉树的最小叶节点,然后将其保存起来,最后返回值直接返回这个最小叶节点的,因为这个最小叶节点也就是链表的头结点了,代码如下:
但是在牛客网的编译器里却不对,不知道为什么,是因为内存太大了吗?
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==NULL) return NULL;
findHead(pRootOfTree);//在改变二叉树结构之前先找出头结点,并保存
midTranverse(pRootOfTree);
return head;
}
private:
TreeNode* head;
TreeNode* pre=NULL;//设置一个前驱节点,用来记忆遍历的时候当前节点的上一个节点
void findHead(TreeNode* node)
{
if (node->left == NULL&&node->right == NULL)
{
head = node;
return;
}
findHead(node->left);
}
//二叉树中序遍历
void midTranverse(TreeNode* node)
{
if(node==NULL)
{
return;
}
midTranverse(node->left);
node->left=pre;
if(pre) pre->right=node;
pre=node;
midTranverse(node->right);
}
};