法一 中序遍历把遇到的节点合并到链表中
class Solution {
public:
//定义2个指针,分别指向双向链表正向和逆向的头节点
TreeNode *lefthead=nullptr;
TreeNode *righthead=nullptr;
//递归函数
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==nullptr)
return nullptr;
//中序遍历,左,中,右
Convert(pRootOfTree->left);
//旨在把最左边的叶子节点(也可以看作无左右子树的根节点)当作头节点
if(righthead==nullptr)
{
lefthead=pRootOfTree;
righthead=pRootOfTree;
}
//把遍历到的节点加入到我们的链表中去(通过改变指针指向),并后移righthead
else
{
pRootOfTree->left=righthead;
righthead->right=pRootOfTree;
righthead=pRootOfTree;
}
//继续遍历右子树
Convert(pRootOfTree->right);
//最后返回链表的头节点
return lefthead;
}
};
法二:中序遍历的非递归(修改当前遍历节点与之前节点的指针指向)
首先复习下中序遍历的非递归代码
void Inorder(BinaryTree *root)
{
if(!root)
return;
stack<BinaryTree *> s;
BinaryTree *p=root;
while(p||!s.empty())
{
while(!p)
{
s.push(p);
p=p->left;
}
if(!s.empty())
{
printf("%d",s.top()->value);
s.pop();
p=p->right;
}
}
}
关于三种遍历方式的非递归写法参见博客
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==nullptr)
return nullptr;
stack<TreeNode *> s;
TreeNode *pre=nullptr;
TreeNode *p=pRootOfTree;
//把遍历到的第一个节点作为链表的头节点
bool isFirst=true;
while(p||!s.empty())
{
while(p)
{
s.push(p);
p=p->left;
}
p=s.top();
s.pop();
//若是第一个节点,作为头节点
if(isFirst)
{
pRootOfTree=p;
pre=p;
isFirst=false;
}
//否则,修改当前节点与pre节点的指针关系,也相当于一步步把遍历到的节点加到之前链表尾部
else
{
pre->right=p;
p->left=pre;
pre=p;
}
p=p->right;
}
return pRootOfTree;
}
};
法三 最容易理解
思路 1 将左子树构造成双向链表,返回头节点
2 定位到尾节点
3 若左子树不空,把根节点加到链表的尾部
4 将右子树构造成双向链表,返回头节点,若右子树不为空,加到链表的尾部。
5 根据左子树的链表是否为空选择返回的节点(若为空,返回根节点,否则返回左子树链表的头节点)。
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(!pRootOfTree)
return nullptr;
TreeNode *head=Convert(pRootOfTree->left);
TreeNode *tail=head;
if(tail)
{
while(tail->right)
{
tail=tail->right;
}
tail->right=pRootOfTree;
pRootOfTree->left=tail;
}
TreeNode *rhead=Convert(pRootOfTree->right);
if(!rhead)
{
rhead->left=pRootOfTree;
pRootOfTree->right=rhead;
}
return head!=nullptr?head:pRootOfTree;
}
};
发生错误,猜测是循环太多,可以改进定位到左子链最后一个节点的代码。
class Solution {
public:
TreeNode *last=nullptr;
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==nullptr)
return nullptr;
if(pRootOfTree->left==nullptr&&pRootOfTree->right==nullptr)
{
last=pRootOfTree;
return pRootOfTree;
}
TreeNode *head=Convert(pRootOfTree->left);
if(head)
{
last->right=pRootOfTree;
pRootOfTree->left=last;
}
last=pRootOfTree;
TreeNode *lhead=Convert(pRootOfTree->right);
if(lhead)
{
lhead->left=last;
last->right=lhead;
}
return head!=nullptr?head:pRootOfTree;
}
};
依然没有通过难受
扫描二维码关注公众号,回复:
5143857 查看本文章