[Leetcode]Populating Next Right Pointers in Each Node

Given a binary tree

    struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *next;
    }

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.

Initially, all next pointers are set to NULL.

Note:

  • You may only use constant extra space.
  • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree,

         1
       /  \
      2    3
     / \  / \
    4  5  6  7

After calling your function, the tree should look like:

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL


可以分别用递归和非递归的形式实现。递归比较好理解。非递归形式需要利用一个栈,做一个类似中序遍历的东西,相对比较复杂,感觉这个题用非递归没有任何好处,就不详细讲了。

递归方法主要利用的是对每一个节点的操作都是一样的特点。操作包括:

1. 如果节点为空,返回

2. 如果节点左节点非空(由于这是一颗perfect tree,所以一定也有右节点),另左节点的next指向又节点

3. 如果右节点非空(事实上左节点为非空即可证明又节点也非空,但便于理解,把右节点分开来表示)并且他们父亲节点的next也非空,另右节点next等于父节点next的左节点


递归代码如下:

public void connect(TreeLinkNode root) {
        if (root == null) {
            return;
        }
        
        if (root.left != null) {
            root.left.next = root.right;
            //This is the best implementation because root.right cannot be null here
            // if (root.next != null) {
            //     root.right.next = root.next.left;
            // }
        }
        
        if (root.right != null && root.next != null) {
            root.right.next = root.next.left;
        }
        
        connect(root.left);
        connect(root.right);
    }


非递归程序用了相同的逻辑,但是其使用栈来解决遍历问题。每次遍历一个节点,将其压栈,等到遍历节点为空时,pop一个节点出来继续遍历,实现如下:

public void connect(TreeLinkNode root) {
        if (root == null) {
            return;
        }
        Stack<TreeLinkNode> s = new Stack<TreeLinkNode>();
        
        while (root != null || !s.empty()) {
            while (root != null) {
                s.push(root);
                if (root.left != null) {
                    root.left.next = root.right;
                    // if (root.next != null) {
                    //     root.right.next = root.next.left;
                    // }
                }
                if (root.right != null && root.next != null) {
                    root.right.next = root.next.left;
                }
                root = root.left;
            }
            root = s.pop();
            root = root.right;
        }
    }



update 11/15/2014

今天发现更好的方法,直接把这个问题的I,II都覆盖了,而且思路简单,就用层序遍历就好了,每次从队列里弹出的时候都维护一个previous指针用来指向上一个,如果上一个节点存在,就另其next等于当前节点。这个方法无论是完全二叉树还是一般二叉树都OK。


public void connect(TreeLinkNode root) {
        if (root == null) 
            return;
        
        Queue<TreeLinkNode> q = new LinkedList<TreeLinkNode>();
        q.add(root);
        int levelNum = 1;
        
        while (!q.isEmpty()) {
            TreeLinkNode pre = null;
            for (int i = 0; i < levelNum; i++) {
                TreeLinkNode node = q.poll();
                if (node == null)
                    continue;
                q.add(node.left);
                q.add(node.right);
                if (pre != null) {
                    pre.next = node;
                }
                pre = node;
            }
            levelNum = q.size();
        }
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值