【剑指offer】【树】36. 二叉搜索树与双向链表
题目链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/
递归实现1
- 二叉搜索树进行中序遍历会得到递增排序的序列;
- 将递增排序的序列中每个元素的left和right修改,用两个指针pre和cur完成。pre指的是中序遍历上一个访问的节点,cur表示中序遍历当前访问的节点。那么将pre -> right指向cur,cur -> left指向pre即可;
- 处理头和尾,中序遍历完成后,pre指向最后一个节点,头结点如何得到?将第一个访问的节点赋值给head。且第一个节点被访问时,pre的值为NULL,这个节点为head。
时间复杂度:O(n)
空间复杂度:O(n)
/*
// 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 *pre, *head;
Node* treeToDoublyList(Node* root) {
if(!root) return root;
dfs(root);
head -> left = pre;
pre-> right = head;
return head;
}
void dfs(Node *cur)
{
if(!cur) return ;
dfs(cur-> left);
if(!pre) head = cur;
else
{
pre -> right = cur;
cur-> left = pre;
}
pre = cur;
dfs(cur-> right);
}
};
递归实现2
用flag指示返回最左/最右节点,递归后序遍历操作
/*
// 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* treeToDoublyList(Node* root) {
root = treeToDoublyList(root, 0);
if(!root) return NULL;
Node* p = root;
while(p -> right) p = p -> right;
p -> right = root;
root -> left = p;
return root;
}
Node* treeToDoublyList(Node *root, int flag)
{
if(root == NULL) return NULL;
Node *left_ = treeToDoublyList(root -> left, 1);
Node *right_ = treeToDoublyList(root -> right, 0);
root -> left = left_;
root -> right = right_;
if(left_) left_ -> right = root;
if(right_) right_ -> left = root;
Node *p = root;
if(!flag) while(p -> left) p = p -> left;
else while(p -> right) p = p -> right;
return p;
}
};
知识的价值不在于占有,而在于使用