【链表&树】——剑指 Offer 36. 二叉搜索树与双向链表

132 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

题目

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

思路

1.二叉搜索树中序遍历的结果是有序的,利用一个ArrayList集合存储这些有序结果

2.对第一个节点和最后一个节点特殊处理,其他节点left指向上一个,right指向下一个

3.只有一个节点的情况直接让left和right指向自己然后返回

代码

class Solution {
    List<Node> list = new ArrayList<>();

    public Node treeToDoublyList(Node root) {
        if (root == null) return null;
        if (root.left == null && root.right == null) {  //如果只有一个的情况让它left和right都指向自己
            root.left = root;
            root.right = root;
            return root;
        }
        infixorder(root); //中序遍历,二叉搜索树中序遍历的结果是有序的
        list.get(0).left = list.get(list.size() - 1);  //需要对第一个节点特殊处理,left指向最后一个节点
        list.get(0).right = list.get(1);
        for (int i = 1; i < list.size() - 1; i++) {   //最第2 - 第 n-1个节点进行相同的操作
            Node cur = list.get(i);
            cur.left = list.get(i - 1);   //left指向上一个
            cur.right = list.get(i + 1);  //right指向下一个

        }
        list.get(list.size() - 1).left = list.get(list.size() - 2); 
        list.get(list.size() - 1).right = list.get(0); //对最后一个节点特殊处理,right指向第一个节点
        return list.get(0);
    }

    public void infixorder(Node root) {   //中序遍历,利用ArrayList集合存储这些有序节点
        if (root.left != null) {
            infixorder(root.left);
        }
        list.add(root);
        if (root.right != null) {
            infixorder(root.right);
        }
    }
}
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;
    }
}