二叉树相关

有一棵二叉树,请设计一个算法,按照层次打印这棵二叉树。

给定二叉树的根结点root,请返回打印结果,结果按照每一层一个数组进行储存,所有数组的顺序按照层数从上往下,且每一层的数组内元素按照从左往右排列。保证结点数小于等于500。

public class TreeNode {
	int val = 0;
	TreeNode left = null;
	TreeNode right = null;
	public TreeNode(int val){
		this.val = val;
	}
}
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class TreePrinter {
	public static int[][] printTree(TreeNode root){
		TreeNode last;			//指向当前节点
		TreeNode nlast;			//指向当前节点下一行的最后一个节点
		last = root;
		nlast = last;
		Queue<TreeNode> que = new LinkedList<TreeNode>();
		que.offer(root);
	
		ArrayList<ArrayList<Integer>> store = new ArrayList<ArrayList<Integer>>();
		store.add(new ArrayList<Integer>());
		int hight = 0;
		while(!que.isEmpty()){
			TreeNode out = que.poll();
			//System.out.print(out.val+" ");
			store.get(hight).add(out.val);
			
			
			if(out.left!=null){
				que.offer(out.left);
				nlast = out.left;
			}
			
			if(out.right!=null){
				que.offer(out.right);
				nlast = out.right;
			}
			
			if(out==last){
				//System.out.println();
				last = nlast;
				hight++;
				store.add(new ArrayList<Integer>());
			}
		}
		int[][] show = new int[hight][];
		for(int i = 0;i < store.size()-1; i++){
			ArrayList<Integer> temp = store.get(i);
			System.out.println("size: "+temp.size());
			show[i] = new int[temp.size()];
			for(int j = 0;j < temp.size(); j++){
				show[i][j] = temp.get(j);
				System.out.print(temp.get(j)+" ");
			}
			System.out.println();
		}
		return show;
	}
	public static void main(String[] args) {
		TreeNode root = new TreeNode(1);
		root.left = new TreeNode(2);
		root.left.right = new TreeNode(3);
		root.left.right.left = new TreeNode(4);
		root.left.right.right = new TreeNode(5);
		
		int[][] result = printTree(root);
		
	}
}

  

请用递归方式实现二叉树的先序、中序和后序的遍历打印。

给定一个二叉树的根结点root,请依次返回二叉树的先序,中序和后续遍历(二维数组的形式)。

	public void FirstSearch(TreeNode cur,ArrayList list){
		if(cur==null)
			return ;
		list.add(cur.val);
		FirstSearch(cur.left,list);
		FirstSearch(cur.right,list);
	}
	public void MiddleSearch(TreeNode cur,ArrayList list){
		if(cur==null)
			return ;
		MiddleSearch(cur.left,list);
		list.add(cur.val);
		MiddleSearch(cur.right,list);
	}
	public void LastSearch(TreeNode cur,ArrayList list){
		if(cur==null)
			return ;
		LastSearch(cur.left,list);
		LastSearch(cur.right,list);
		list.add(cur.val);
	}
	public int[][] convert(TreeNode root) {
        // write code here
		ArrayList<Integer> nodeList = new ArrayList<Integer>();
		FirstSearch(root,nodeList);
		int[][] result = new int[3][nodeList.size()];
		for(int i = 0;i < nodeList.size(); i++)
			result[0][i] = nodeList.get(i);
		nodeList.clear();
		
		MiddleSearch(root,nodeList);
		for(int i = 0;i < nodeList.size(); i++)
			result[1][i] = nodeList.get(i);
		nodeList.clear();
		
		LastSearch(root,nodeList);
		for(int i = 0;i < nodeList.size(); i++)
			result[2][i] = nodeList.get(i);
		nodeList.clear();
		
		return result;
	}

  

首先我们介绍二叉树先序序列化的方式,假设序列化的结果字符串为str,初始时str等于空字符串。先序遍历二叉树,如果遇到空节点,就在str的末尾加上“#!”,“#”表示这个节点为空,节点值不存在,当然你也可以用其他的特殊字符,“!”表示一个值的结束。如果遇到不为空的节点,假设节点值为3,就在str的末尾加上“3!”。现在请你实现树的先序序列化。

给定树的根结点root,请返回二叉树序列化后的字符串。

	public void FristSearch(TreeNode cur,StringBuffer sb){
		if(cur==null){
			sb.append("#!");
			return ;
		}
		sb.append(cur.val+"!");
		FristSearch(cur.left,sb);
		FristSearch(cur.right,sb);
	}
	public String toString(TreeNode root) {
	        // write code here
		StringBuffer sb = new StringBuffer();
		FristSearch(root,sb);
		return sb.toString();
	}

  

有一棵二叉树,请设计一个算法判断这棵二叉树是否为平衡二叉树。

给定二叉树的根结点root,请返回一个bool值,代表这棵树是否为平衡二叉树。

class TreeNode {
	int val = 0;
	TreeNode left = null;
	TreeNode right = null;
	public TreeNode(int val) {
		this.val = val;
	}
}

  
 public int Search(TreeNode cur,int level,boolean[] result){
    	if(cur==null)
    		return level;
    	if(!result[0])
    		return level;
    	int lH = Search(cur.left,level+1,result);
    	if(!result[0])
    		return level;
    	int rH = Search(cur.right,level+1,result);
    	
    	if(Math.abs(lH-rH)>1)
    		result[0] = false;
    	return Math.max(lH, rH);
    }
    public boolean check(TreeNode root) {
        // write code here
    	boolean[] result = new boolean[1];
    	result[0] = true;
    	Search(root,1,result);
    	return result[0];
    }

  解法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 CheckBalance {
     public static boolean check(TreeNode root){
        return chk(root)>=0;
    }

    private static int chk(TreeNode root) {
        if (root==null) return 0;
        int l=chk(root.left),r=chk(root.right);//左右两边深度
        if (l<0||r<0) return -1;
        if ((Math.abs(r-l)>1))return -1;//当左右两边深度差超过1时 返回-1
        return r>l?r+1:l+1;
    }
}

  

一棵二叉树原本是搜索二叉树,但是其中有两个节点调换了位置,使得这棵二叉树不再是搜索二叉树,请找到这两个错误节点并返回他们的值。保证二叉树中结点的值各不相同。

给定一棵树的根结点,请返回两个调换了位置的值,其中小的值在前。

核心代码:

public int[] findError(TreeNode root) {
        // write code here
        int res[]=new int[2];
        TreeNode err[]=new TreeNode[2];
        Stack<TreeNode> st=new Stack<TreeNode>();
        TreeNode pre=null;
      while(!st.isEmpty()||root!=null){
          if(root!=null){
              st.push(root);
              root=root.left;
          }else{
              root=st.pop();
              if(pre!=null&&pre.val>root.val){
                  err[0]=err[0]==null?pre:err[0];
                  err[1]=root;
              }
              pre=root;
              root=root.right;
          }
           
      }
        res[1]=err[0].val;
        res[0]=err[1].val;
        return res;
    }

解法二:

public class FindErrorNode {
     public int[] findError(TreeNode root) {
        // write code here
    	ArrayList<Integer> list = new ArrayList<Integer>();
    	int[] result = new int[2];
    	LastSearch(root,list);
    	int count = 0;
    	for(int i = 0;i < list.size()-1; i++)
    		if(list.get(i)>list.get(i+1)){
    				result[1] = list.get(i+1);
    			if(count==0){
    				result[0] = list.get(i);
    				//result[1] = list.get(i+1)
    			}
            	count++;
    		}
    		result[0] = result[0]^result[1];
    		result[1] = result[0]^result[1];
    		result[0] = result[0]^result[1];

    	return result;
    }
    private void LastSearch(TreeNode cur,List list){
    	if(cur==null){
    		return ;
    	}
    	LastSearch(cur.left,list);
    	list.add(cur.val);
        LastSearch(cur.right,list);
    }
}

  

请用非递归方式实现二叉树的先序、中序和后序的遍历打印。

给定一个二叉树的根结点root,请依次返回二叉树的先序,中序和后续遍历(二维数组的形式)。

package com.oj;

import java.util.ArrayList;
import java.util.Stack;

class TreeNode {
	int val = 0;
	TreeNode left = null;
	TreeNode right = null;
	public TreeNode(int val) {
		this.val = val;
	}
}
public class TreeSearch {
	public void PreSearch(TreeNode root,ArrayList<Integer> list){
		Stack stack = new Stack();
		stack.push(root);
		while(!stack.isEmpty()){
			TreeNode temp = (TreeNode) stack.pop();
			list.add(temp.val);
			if(temp.right!=null)
				stack.push(temp.right);
			if(temp.left!=null)
				stack.push(temp.left);
		}
	}
	public void MidSearch(TreeNode root,ArrayList<Integer> list){
		Stack stack = new Stack();
		TreeNode cur = root;
		stack.push(cur);
		cur = cur.left;
		while(!stack.isEmpty()||cur!=null){
			if(cur!=null){
				stack.push(cur);
				cur = cur.left;
			}else{
				cur = (TreeNode) stack.pop();
				list.add(cur.val);
				cur = cur.right;
			}
		}
	}
	
	public void LastSearch(TreeNode root,ArrayList<Integer> list){
		Stack s1 = new Stack();
		Stack s2 = new Stack();
		TreeNode cur = root;
		s1.push(cur);
		while(!s1.isEmpty()){
			cur = (TreeNode) s1.pop();
			s2.push(cur);
			if(cur.left!=null){
				s1.push(cur.left);
			}
			if(cur.right!=null){
				s1.push(cur.right);
			}
		}
		while(!s2.isEmpty()){
			TreeNode temp = (TreeNode) s2.pop();
			list.add(temp.val);
		}
	}
	
	public int[][] convert(TreeNode root) {
	        // write code here
		int[][] result = new int[3][];
		ArrayList<Integer> list = new ArrayList<Integer>();
		PreSearch(root,list);
		result[0] = new int[list.size()];
		for(int i = 0;i < list.size(); i++){
			result[0][i] = list.get(i);
		}
		list.clear();
		
		MidSearch(root,list);
		result[1] = new int[list.size()];
		for(int i = 0;i < list.size(); i++){
			result[1][i] = list.get(i);
		}
		list.clear();
		
		LastSearch(root,list);
		result[2] = new int[list.size()];
		for(int i = 0;i < list.size(); i++){
			result[2][i] = list.get(i);
		}
		
		return result;
    }
	
}

  

从二叉树的节点A出发,可以向上或者向下走,但沿途的节点只能经过一次,当到达节点B时,路径上的节点数叫作A到B的距离。对于给定的一棵二叉树,求整棵树上节点间的最大距离。

给定一个二叉树的头结点root,请返回最大距离。保证点数大于等于2小于等于500.

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
public class LongestDistance {
    public int findLongest(TreeNode root) {
  			int[]record=new int[1];
        	return process(root,record);
         }
    public int process(TreeNode root,int[]record){
        if(root==null){
            record[0]=0;
            return 0;
        }
        int lmax=process(root.left,record);
        int maxfromleft=record[0];
        int rmax=process(root.right,record);
        int maxfromright=record[0];
        int cur=maxfromleft+maxfromright+1;
        
        record[0]=Math.max(maxfromleft,maxfromright)+1;
                
        return Math.max(Math.max(lmax,rmax),cur);      
    }
}

  

题目描述:重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
	public TreeNode ConstructTree(int[] pre,int[] in,int prestart,int preend,int instart,int inend) throws Exception
	{
		int rootvalue = pre[prestart];
		TreeNode root = new TreeNode(rootvalue);
		root.left = null;
		root.right = null;
		
		if(prestart==preend){
			if(instart==inend&&pre[prestart]==in[instart])
				return root;
			else
				throw new Exception("wrong");
		}
		
		int posinorder = instart;
		while(posinorder<=inend&&in[posinorder]!=rootvalue)
			++posinorder;
		
		if(posinorder==inend&&in[posinorder]!=rootvalue)
			throw new Exception("wrong");
		
		int leftLength = posinorder-instart;
		int leftPreend = prestart+leftLength;
		if(leftLength>0)
		{
			root.left = ConstructTree(pre,in,prestart+1,leftPreend,instart,posinorder-1);
		}
		if(leftLength<preend-prestart)
		{
			root.right = ConstructTree(pre,in,leftPreend+1,preend,posinorder+1,inend);
		}
		return root;
	}
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        int prestart = 0, preend = pre.length-1;
        int instart = 0, inend = in.length-1;
        if(preend==0||inend==0)
        	return null;
        try {
			return ConstructTree(pre,in,prestart,preend,instart,inend);
		} catch (Exception e) {
			//e.printStackTrace();
			return null;
		}
    }
}

  

posted @ 2016-05-06 10:59  再见,少年  Views(359)  Comments(0Edit  收藏  举报