题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路1:递归——按照中序遍历 左根右,先找到左子树的最左头节点;将根节点连接到左子树最右边节点;再找到右子树的最左节点,链接到根节点右边。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
//双向链表的左边头结点和右边头结点
TreeNode* leftHead = nullptr;
TreeNode* rightHead = nullptr;
TreeNode* Convert(TreeNode* pRootOfTree)
{
//递归调用叶子节点的左右节点返回nullptr
if(pRootOfTree== nullptr)
return nullptr;
//第一次运行时,会使最左边叶子节点为链表的第一个节点
Convert(pRootOfTree->left);
if(rightHead== nullptr)
leftHead = rightHead=pRootOfTree;
else{
//把根节点插入到双向链表右边,rightHead向右移动
rightHead->right = pRootOfTree;
pRootOfTree->left = rightHead;
rightHead = pRootOfTree;
}
//把右叶子节点也插入到双向链表
Convert(pRootOfTree->right);
//返回左边头结点
return leftHead;
}
};
思路2:非递归——栈
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
TreeNode *head = NULL, *pre = NULL; //head 输出,pre记录上一次出栈值
stack<TreeNode*> s;
while (pRootOfTree || !s.empty())
{
while (pRootOfTree) //if(pRootOfTree!=nullptr),写入栈,并遍历到最左
{
s.push(pRootOfTree);
pRootOfTree = pRootOfTree->left;
}
if (!s.empty())
{
pRootOfTree = s.top();
s.pop();
if (pre != NULL)
{
pre->right = pRootOfTree;
pRootOfTree->left = pre;
}
else //pre为空,表示s第一次出栈,第一次出栈值为最左值,即输出值
{
head = pRootOfTree;
}
pre = pRootOfTree;
pRootOfTree = pRootOfTree->right;
}
}
return head;
}
};