Loading

剑指 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};
    }
}
posted @ 2021-03-01 16:33  yoyuLiu  阅读(56)  评论(0编辑  收藏  举报