378.将二叉查找树转换成双链表

描述

将一个二叉查找树按照中序遍历转换成双向链表。

样例

给定一个二叉查找树:

        4
       / \
      2   5
     / \
    1   3

返回 1<->2<->3<->4<->5。

思路

  1. 分别将 BST 的左、右子树转换成双向链表
  2. 新建出一个链表结点,值等于 BST 根节点的值。由于是 BST,所以 new 出的结点应该位于链表的中间,所以分别连接左、右子树转换成的链表。这一步要找到左链表的尾结点和右链表的头结点
  3. 特殊情况的判别,左链表或右链表为空;以及递归出口
    最后返回链表头结点即可

代码

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 * Definition for Doubly-ListNode.
 * public class DoublyListNode {
 *     int val;
 *     DoublyListNode next, prev;
 *     DoublyListNode(int val) {
 *         this.val = val;
 *         this.next = this.prev = null;
 *     }
 * }
 */ 
 
// 首先的前提是二叉树本身已经是二叉查找树
class ResultType {
    DoublyListNode first, last;
    // first 和 last 代表一段链表的头尾结点
    public ResultType(DoublyListNode first, DoublyListNode last) {
        this.first = first;
        this.last = last;
    }
}

public class Solution {
    /**
     * @param root: The root of tree
     * @return: the head of doubly list node
     */
    public DoublyListNode bstToDoublyList(TreeNode root) {  
        if (root == null) {
            return null;
        }
        
        ResultType result = helper(root);
        return result.first;
    }
    
    // helper 函数的作用,计算出一颗二叉树按中序遍历形成链表的头尾结点
    public ResultType helper(TreeNode root) {  
        // 递归出口
        if (root == null) {
            return null;
        }
        
        ResultType left = helper(root.left);
        ResultType right = helper(root.right);
        
        // 新建一个结点 node 值等于根结点的值
        DoublyListNode node = new DoublyListNode(root.val);
        
        // result 用于存储链表最终结果
        ResultType result = new ResultType(null, null);
        
        if (left == null) {
            result.first = node;
        // 如果左子树不为空,将左子树的最右结点和 node 双向连接
        // 左子树形成的链表添加到 result
        } else {
            result.first = left.first;
            left.last.next = node;
            node.prev = left.last;
        }
        
        if (right == null) {
            result.last = node;
        // 如果右子树不为空,将右子树的最左结点和 node 双向连接
        // 右子树形成的链表添加到 result
        } else {
            result.last = right.last;
            right.first.prev = node;
            node.next = right.first;
        }
        
        return result;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容