LeetCode155 将二叉搜索树转化为排序的双向链表

28 阅读1分钟

leetcode.cn/problems/er…

解法一:中序遍历

image.png

type Node struct {
    Val   int
    Left  *Node
    Right *Node
}

// 全局变量:创建前驱节点和头结点的引用
var pre, head *Node

// treeToDoublyList 将二叉搜索树转换为循环双向链表
// 中序遍历完成后,head指向双向链表中的头结点,pre指向尾节点
func treeToDoublyList(root *Node) *Node {
    if root == nil {
        return nil
    }
    pre, head = nil, nil // 初始化全局变量
    dfs(root)            // 中序遍历构建双向链表
    
    // 由于要求是循环链表,需要再修改头尾节点的指针指向
    head.Left = pre
    pre.Right = head
    return head
}

// dfs 递归实现中序遍历
// 中序遍历顺序为:左子树 → 当前节点 → 右子树
func dfs(cur *Node) {
    if cur == nil {
        return // 越过叶子节点,直接返回
    }
    dfs(cur.Left) // 递归中序遍历左子树
    
    // -----中序遍历处理逻辑-----
    
    // pre用于记录双向链表中位于cur左侧的节点,即上一次迭代中的cur
    if pre == nil {
        // 当pre==nil时,说明cur左侧没有节点,即此时cur为双向链表中的头节点
        head = cur
    } else {
        // 反之,pre不为空,cur左侧存在节点,此时需要修改双向链表节点的指向
        pre.Right = cur
        cur.Left = pre
    }
    pre = cur // 更新pre为当前节点,用于下一次迭代
    
    dfs(cur.Right) // 递归中序遍历右子树
}