剑指 Offer 36. 二叉搜索树与双向链表(426. 将二叉搜索树转化为排序的双向链表)

题目:

思路:

【1】这道题本身的思路就是对树进行中序遍历,然后将其按中序遍历的顺序变成链表,而且在于不能创建新的节点:

【2】递归是最为简单的中序遍历:

// 打印中序遍历
void dfs(Node root) {

    if(root == null) return;

    dfs(root.left); //

    System.out.println(root.val); //

    dfs(root.right); //

}

 

【3】最简单的方法就是利用辅助空间进行记录中序遍历的节点指向,全部记录下来后再进行变更左右节点的指引。但这种消耗的空间有点大,不是最优的。

【4】优化一点的就可以采用两个节点变量,head和pre,pre是表示当前节点的上一个节点,head表示头结点,cur表示当前节点。如果pre=null,就代表还没设置头结点。所以此时要设置head节点,其次,操作完后要设置pre=cur,因为cur会是下一个节点的pre,所以除了一开始pre会是null,后面都不会为null。而且在最后的时候因为最后一个右结点的指向是null,所以pre就会指向最后的右结点。故一切就会变得简单了起来。

 

代码展示:

借助两个变量进行对树转成双向链表:

//时间0 ms击败100%
//内存41 MB击败42.56%
//时间复杂度 O(N) : N 为二叉树的节点数,中序遍历需要访问所有节点。
//空间复杂度 O(N) : 最差情况下,即树退化为链表时,递归深度达到 N,系统使用 O(N) 栈空间。
/*
// 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 {
    Node pre, head;

    public Node treeToDoublyList(Node root) {

        if(root == null) return null;

        dfs(root);

        head.left = pre;

        pre.right = head;

        return head;

    }

    void dfs(Node cur) {

        if(cur == null) return;

        dfs(cur.left);
        
        //pre用于记录双向链表中位于cur左侧的节点,即上一次迭代中的cur,当pre==null时,cur左侧没有节点,即此时cur为双向链表中的头节点
        if(pre==null) head = cur;
        //反之,pre!=null时,cur左侧存在节点pre,需要进行pre.right=cur的操作。
        else pre.right = cur;
        cur.left = pre;//pre是否为null对这句没有影响,且这句放在上面两句if else之前也是可以的。
        pre = cur;//pre指向当前的cur

        dfs(cur.right);//全部迭代完成后,pre指向双向链表中的尾节点

    }
}

当然如果看起来比较模糊的话,换另一中写法可能更清晰:

public void dfs(Node root){
    if(root==null) return;
    dfs(root.left);
    if(pre==null){
        head = root;
        pre = head;
    }else{
        pre.right = root;
        root.left = pre;
        pre = root;
    } 
    dfs(root.right);
}

 

posted @ 2023-02-06 16:19  忧愁的chafry  阅读(12)  评论(0编辑  收藏  举报