leetcode:二叉搜索树转化为双向链表(五)

707 阅读2分钟

题目:

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

题解:

class Solution {
    Node head, pre;
    public Node treeToDoublyList(Node root) {
        if(root==null) return null;
        dfs(root);

        pre.right = head;
        head.left =pre;//进行头节点和尾节点的相互指向,这两句的顺序也是可以颠倒的

        return head;

    }

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

        pre = cur;//pre指向当前的cur

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

//by:krahets

解题思路:

本文解法基于性质:二叉搜索树的中序遍历为递增序列 。

将二叉搜索树 转换成一个 “排序的循环双向链表” ,其中包含三个要素: 

排序链表: 节点应从小到大排序,因此应使用 中序遍历 “从小到大”访问树的节点; 

双向链表: 在构建相邻节点(设前驱节点 prepre ,当前节点 curcur )关系时,不仅应 pre.right = cur,也应 cur.left = pre

循环链表:设链表头节点 head 和尾节点 tail ,则应构建 head.left = tail和 tail.right = head 

// 打印中序遍历
void dfs(TreeNode root) {
    if(root == null) return;
    dfs(root.left); // 左
    System.out.println(root.val); // 根
    dfs(root.right); // 右
}

心得经验:

上面是中序遍历的大概历程,以上的都是在中序遍历的框架里进行拓展

记住,当在java中进行这种类似于树中的节点或者链表中节点进行交换或者赋值时:

有这样的规则:

 r=r—>next

要让r往后进一步,那么就要用到这样的形式

pre.next = cur

cur.pre = pre

要让其建立起双链表的形式,就是pre向后指向cur,cur向前指向pre,那么就是这样的形式,=的前后就是其指向的顺序