二叉搜索树转双向链表
题目
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
思路:
-
C++
(1)设置两个指针:head指向已改好的链表的头节点,tail/pre指向其尾节点;
(2)先序递归实现,处理根节点时左子树已经是一个排序好的链表了,将根节点加入链表即可。
(3)所有的完成后将头尾相连变成双向循环链表。 -
python
(1)递归函数Convert返回以root为根的二叉搜索树转换后链表的头尾节点;
(2)在Convert中先得到根节点的左右子树转换后链表的头尾节点,再把这三部分(左,根,右)连成完整的链表
C++
/*
// 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) {
if(!root)
return nullptr;
Node* head = nullptr;
Node* tail = nullptr;
Convert(root, head, tail);
//要求循环双向链表,还要将头尾相连
head->left = tail;
tail->right = head;
return head;
}
private:
void Convert(Node* root, Node*& head, Node*& tail)
{
if(!root)
return ;
// 中序处理
//左子树
Convert(root->left, head, tail);
//根 //此时左子树为空,链表的头节点为根节点
if(head == nullptr)
{
head = root;
tail = root;
}
else //此时左子树已经是一个排序好的双向链表,pre指向它的最后一个元素
{
tail->right = root;
root->left = tail;
tail = root;
}
//右子树
Convert(root->right, head, tail);
}
};
python
class Solution:
# Convert返回以root为根的二叉搜索树转换后链表的头尾节点
def convert(self, root: 'Node') -> ('Node', 'Node'):
if root is None:
return None, None
# 左子树 对应的 双向链表的头节点和尾节点
left_head, left_tail = self.convert(root.left)
# 右子树 对应的 双向链表的头节点和尾节点
right_head, right_tail = self.convert(root.right)
# 将根节点与左右子树相连
root.left, root.right = left_tail, right_head
if left_tail:
left_tail.right = root
if right_head:
right_head.left = root
# 左子树的头节点为空时,当前链表的头节点为根节点
if left_head==None:
left_head = root
# 右子树的尾节点为空时,当前链表的尾节点为根节点
if right_tail==None:
right_tail = root
return left_head , right_tail
def treeToDoublyList(self, root: 'Node') -> 'Node' or None:
head, tail = self.convert(root)
# 头尾相连,构成双向循环链表
if head and tail:
head.left = tail
tail.right = head
return head