方法一:中序遍历:时间 O(n),空间 O(n)
解题思路:
- 二叉搜索树的中序遍历是一个递增的序列
- 因此遍历二叉树,回溯前需要记录前驱节点
- 在左树回溯之后将前驱节点和当前节点进行链接
题解
- 记录一个头结点 head 和前驱节点 prev,对二叉树进行中序遍历
- 左树回溯的时候进行判断,若head为空说明到达了值最小的头结点,让 head = prev = root
- 若 head 不空,则将 root 的左树指向 prev ,prev的右树指向 root,并调整prev指向root
- 遍历右树,递归结束之后链接头尾指针域
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node() {}
Node(int _val) {
val = _val;
left = NULL;
right = NULL;
}
Node(int _val, Node* _left, Node* _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
public:
Node* head = nullptr, *pre = nullptr;
Node* treeToDoublyList(Node* root)
{
if (root == nullptr)
return root;
exchangeTree(root);
// 递归结束pre指向的就是最后一个节点,因此不需要通过返回值找最后的节点
head->left = pre;
pre->right = head;
return head;
}
void exchangeTree(Node* root)
{
if (root->left)
exchangeTree(root->left);
if (head == nullptr)
{
pre = head = root;
}
else
{
root->left = pre;
pre->right = root;
pre = root;
}
if (root->right)
exchangeTree(root->right);
}
};