[算法]填充二叉树节点的右侧节点

166 阅读2分钟

0x00 题目

给定一个 完美 二叉树 其所有叶子节点都在同一层 每个父节点都有 两个 子节点

填充它的每个 next 指针 让这个指针指向其下一个 右侧 节点 如果找不到下一个右侧节点 则将 next 指针设置为 NULL


0x01 思路

需要把每一层的所有节点 让它的 next 指针指向 右侧 节点 不禁让人想到了 层序 遍历的方式 获取当前层的所有节点,然后一顿操作即可

当然使用 递归 方式也是可以的 把当前节点的 next 指针指向它的 右侧 节点 然后递归,一顿操作即可

粟子:

     3
    /  \
   9    20
  / \   / \
 11  8 15  7
 a   b c   d

a.next = b b.next = c c.next = d

节点 b 与 节点 c 的父节点不一样 所以,操作的时候 应该由 节点来操作 节点的连接


0x02 解法

语言:Swift

树节点:TreeNode

public class TreeNode {
    public var val: Int
    public var left: TreeNode?
    public var right: TreeNode?
    public init() { self.val = 0; self.left = nil; self.right = nil; }
    public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
    public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
        self.val = val
        self.left = left
        self.right = right
    }
}

迭代法:

func connect(_ root: Node?) -> Node? {
    guard let root = root else {
        return nil
    }
    
    // 存储每层的节点
    var queue = [Node]()
    queue.append(root)
    
    while !queue.isEmpty {
        // 存储下一层的节点
        var temp = [Node]()
        var index = 0
        
        // 一顿操作,next 指针的指向
        while index < queue.count - 1 {
            let node = queue[index]
            node.next = queue[index+1]
            index += 1
        }
        
        // 收集下一层的节点
        for node in queue {
            if node.left != nil {
                temp.append(node.left!)
            }
            if node.right != nil {
                temp.append(node.right!)
            }
        }
        
        // 更新
        queue = temp
    }
    
    return root
}

递归法:

func connect(_ root: Node?) -> Node? {
    guard let root = root else { return nil }

    func build(_ left: Node?, _ right: Node?) {
        if left == nil || right == nil{
            return
        }
        
	// 指向右节点
        left?.next = right

	// 一顿操作	
	// 左.左子节点 -> 左.右子节点
        build(left?.left, left?.right)     
        
        // 右.左子节点 -> 右.右子节点
        build(right?.left, right?.right)  
        
        // 左.右子节点 -> 右.左子节点,这一步是重点!!! 少了这一步,就只能连接最左边和最右边了
        build(left?.right, right?.left)    
    }

    // 连接左右节点
    build(root.left, root.right)
    return root
}

0x03 我的小作品

欢迎体验我的作品之一:小汉字-XHanzi
汉字书写入门,常用汉字 3800 个,二级字表 2200 个
App Store 搜索即可~