剑指 Offer 36. 二叉搜索树与双向链表
剑指 Offer 36. 二叉搜索树与双向链表
Difficulty: 中等
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
为了让您更好地理解问题,以下面的二叉搜索树为例:
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。
注意:本题与主站 426 题相同:
注意:此题对比原题有改动。
Solution
思路:采用后序遍历,先获取左子树返回的双向链表,再获取右子树的双向链表。那么根结点就是两个链表的连接点。需要考虑的情况有两个:
- 有左子树,也有右子树
- 左子树或右子树不存在,或者左右子树都不存在
第一种情况很好直接使用返回的值就好。第二种情况,如果左子树不存在,那么当前结点就是表头;如果右子树不存在,那么当前绩点就是表尾;如果都不存在,那么当前双向链表就只有一个结点。
Language: java
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val,Node _left,Node _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
public Node treeToDoublyList(Node root) {
if(root == null) return null;
Node[] res = helper(root);
res[0].left = res[1];
res[1].right = res[0];
return res[0];
}
/*方法返回Node[2],其中Node[0]表示表头,Node[1]表示表尾*/
private Node[] helper(Node root){
if(root == null) return new Node[]{null, null};
Node[] left = helper(root.left);
Node[] right = helper(root.right);
Node head = null, tail = null;
if(left[0] == null && left[1] == null){
head = root; //当前结点没有左子树时,该结点就是表头
}else{
root.left = left[1];
left[1].right = root;
head = left[0];
}
if(right[0] == null && right[1] == null){
tail = root; //当前结点没有右子树时,该结点就是表尾
}else{
root.right = right[0];
right[0].left = root;
tail = right[1];
}
return new Node[]{head, tail};
}
}