程序员面试金典-4.6寻找下一个节点

一、题目描述

请设计一个算法,寻找二叉树中指定结点的下一个结点(即中序遍历的后继)。

给定树的根结点指针TreeNode* root和结点的值int p,请返回值为p的结点的后继结点的值。保证结点的值大于等于零小于等于100000且没有重复值,若不存在后继返回-1。

二、解题思路

1.本题是寻找指定节点的下一个节点(按照中序遍历),首先应该明白什么是中序遍历,后序遍历和前序遍历。

      中序遍历是指按照左中右的方式来遍历一棵树;后序遍历是按照左右中的方式来遍历;先序遍历是按照中左右的方式来遍历。遍历的代码参考http://blog.csdn.net/piaoxue820/article/details/39156649

2.如果采用递归的方式来求解,需要用一个变量来记录目标树节点,这样在遍历下一个节点的时候就可以返回目标树节点的后继节点的值。

3.如果不用递归实现,则需要用到栈,当然也需要一个标记量来记录是否找到了目标树节点,从而输出目标树节点的后继节点值。

三、代码

1.先序遍历、中序遍历和后序遍历的代码

//前序遍历,中左右
	public void preOrder(Node node){
		if(node!=null){
			System.out.print(node.val+",");
			preOrder(node.left);
			preOrder(node.right);
		}
	}
//前序遍历,中左右,非递归
	public void preOrderN(Node node){
		Stack<Node> stack=new Stack<Node>();
		Node cur=node;
		while(cur!=null || !stack.empty()){
			if(cur!=null){
				System.out.print(cur.val);
				stack.push(cur);
				cur=cur.left;
			}else{
				cur=stack.pop();
				cur=cur.right;
			}
		}
	}

//中序遍历,左中右,递归public void inOrder(Node node){if(node!=null){inOrder(node.left);System.out.print(node.val+",");inOrder(node.right);}}

	//中序遍历,非递归
	public void inOrderN(Node node){
		Stack<Node> stack=new Stack<Node>();
		Node cur=node;
		while(cur!=null || !stack.empty()){
			while(cur!=null){
				stack.push(cur);
				cur=cur.left;
			}
			if(!stack.empty()){
				Node qNode=stack.pop();
				System.out.print(qNode.val+",");
				cur=qNode.right;
			}
		}
	}
	//后续遍历 ,左右中
	public void postOrder(Node node){
		if(node!=null){
			postOrder(node.left);
			postOrder(node.right);
			System.out.print(node.val+",");
		}
	}
//后序遍历,左右中,非递归
	public void postOrderN(Node node){
		Stack<Node> stack=new Stack<Node>();
		Stack<Node>  output=new Stack<Node>();
		Node cur=node;
		while(cur!=null || !stack.empty()){
			if(cur!=null){
				output.push(cur);
				stack.push(cur);
				cur=cur.right;
			}else{
				cur=stack.pop();
				cur=cur.left;
			}
		}
		while(!output.empty()){
			System.out.print(output.pop().val+",");
		}
	}


2.本题的代码(注释部分为递归实现,非注释部分为非递归实现)

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
public class Successor {
    TreeNode pre=new TreeNode(-1);
    public int findSucc(TreeNode root, int p) {
        // write code here
        boolean isFound=false;
        Stack<TreeNode> stack=new Stack<TreeNode>();
        TreeNode cur=root;
        while(cur!=null || !stack.empty()){
            while(cur!=null){
                stack.push(cur);
                cur=cur.left;
            }
            if(!stack.empty()){
                TreeNode q=stack.pop();
                if(isFound)
                    return q.val;
                else{
                    if(q.val==p)
                        isFound=true;
                }
                cur=q.right;
            }
          
        }
          return -1;
        /*
        if(root==null)
            return -1;
        int left=findSucc(root.left,p);
        if(left==-1){
            if(pre.val==p)
                return root.val;
            pre=root;
            return findSucc(root.right,p);
        }
        return left;
        */
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值