Java二叉树问题集合


1、递归将二叉树转换为有向链表

2、递归分层遍历二叉树

迭代分层遍历二叉树

3、递归前序遍历

迭代前序遍历

4、递归中序遍历

迭代中序遍历

5、递归后序遍历

迭代后序遍历

6、递归求二叉树深度

迭代求二叉树深度

7、递归求某一节点的深度

迭代求某一节点深度

8、递归求二叉树节点个数

迭代求二叉树节点个数

9、递归求二叉树最大路径和




import java.util.*;

public class BinaryTreeSet {
	public static void main(String[] args){
		Node root=new Node(3);
		root.left=new Node(5);
		root.right=new Node(4);
		root.left.left=new Node(1);
		root.left.left.right=new Node(10);
		root.left.right=new Node(2);
		root.right.left=new Node(7);
		root.right.right=new Node(8);
		root.right.left.left=new Node(6);
		root.right.left.right=new Node(9);
		BinTree bt=new BinTree();
		int totaln=bt.nodeNum2(root);
		System.out.println("总节点数为:"+totaln);
		int maxn=bt.maxPathSum(root);
		System.out.println("最大路径和为:"+maxn);
		int value1=2;
		System.out.println(value1+"在第"+bt.getLayor(root, value1,1)+"层");
		System.out.println(value1+"在第"+bt.getLayor2(root, value1)+"层");
		int dep1=bt.getDepth(root);
		int dep2=bt.getDepth2(root);
		System.out.println("总深度为:"+dep1+"和"+dep2);
		System.out.print("前序遍历结果:");
		bt.preOrderTravel(root);
		System.out.println();
		System.out.print("前序遍历结果:");
		bt.preOrderTravel2(root);
		System.out.println();
		System.out.print("中序遍历结果:");
		bt.inOrderTravel(root);
		System.out.println();
		System.out.print("中序遍历结果:");
		bt.inOrderTravel2(root);
		System.out.println();
		System.out.print("后序遍历结果:");
		bt.postOrderTravel(root);
		System.out.println();
		System.out.print("后序遍历结果:");
		bt.postOrderTravel2(root);
		System.out.println();
		System.out.print("分层遍历二叉树:");
		bt.levelTraversal(root);
		System.out.println();
		System.out.print("分层遍历二叉树:");
		bt.levelTraversal2(root);
		System.out.println();
		System.out.print("转换为双向链表:");
		Node node2=bt.convertBST2DLLRec(root);
		bt.printList(node2);
		System.out.println();
		
		System.out.println();
		
	}
}


class BinTree{
	public BinTree(){
		
	}
	 
	
	//打印链表
	public void printList(Node root){
		while(root!=null){
			System.out.print(root.val+" ");
			root=root.right;
		}
	}
	
	//将二叉树变为有序的双向链表
	public Node convertBST2DLLRec(Node root) {  
        root = convertBST2DLLSubRec(root);         
        // root会在链表的中间位置,因此要手动把root移到链表头  
        while(root.left != null){  
            root = root.left;  
        }  
        return root;  
    }
	// 递归转换BST为双向链表(DLL)
    public Node convertBST2DLLSubRec(Node root){  
        if(root==null || (root.left==null && root.right==null)){  
            return root;
        }
        Node tmp = null;  
        if(root.left != null){          // 处理左子树  
            tmp = convertBST2DLLSubRec(root.left);  
            while(tmp.right != null){   // 寻找最右节点  
                tmp = tmp.right;  
            }
            tmp.right = root;       // 把左子树处理后结果和root连接  
            root.left = tmp;  
        }
        if(root.right != null){     // 处理右子树  
            tmp = convertBST2DLLSubRec(root.right);  
            while(tmp.left != null){    // 寻找最左节点  
                tmp = tmp.left;  
            }  
            tmp.left = root;        // 把右子树处理后结果和root连接  
            root.right = tmp;  
        }  
        return root;  
    } 
	
	//分层遍历二叉树
	//递归
	public void levelTraversal(Node root){
		ArrayList<ArrayList<Integer>> ret=new ArrayList<ArrayList<Integer>>();
		dfs(root,0,ret);
		for(int i=0;i<ret.size();i++){
			for(int j=0;j<ret.get(i).size();j++){
				System.out.print(ret.get(i).get(j)+" ");
			}
		}
	}
	public void dfs(Node root,int level,ArrayList<ArrayList<Integer>> ret){
		if(root==null)
			return;
		if(level>=ret.size()){
			ret.add(new ArrayList<Integer>());
		}
		ret.get(level).add(root.val);
		dfs(root.left,level+1,ret);
		dfs(root.right,level+1,ret);
	}
	
	//迭代
	public void levelTraversal2(Node root){
		if(root==null)
			return;
		LinkedList<Node> queue=new LinkedList<Node>();
		queue.add(root);
		while(!queue.isEmpty()){
			Node cur=queue.removeFirst();
			System.out.print(cur.val+" ");
			if(cur.left!=null){
				queue.add(cur.left);
			}
			if(cur.right!=null){
				queue.add(cur.right);
			}
		}
	}
	
	
	//======前序遍历======================================
	//递归
	public void preOrderTravel(Node root){
		if(root==null)
			return;
		System.out.print(root.val+" ");
		preOrderTravel(root.left);
		preOrderTravel(root.right);
	}
	//迭代
	public void preOrderTravel2(Node root){
		if(root==null)
			return;
		Stack<Node> stack=new Stack<Node>();
		stack.push(root);
		while(!stack.isEmpty()){
			Node cur=stack.pop();
			System.out.print(cur.val+" ");
			if(cur.right!=null){
				stack.push(cur.right);
			}
			if(cur.left!=null){
				stack.push(cur.left);
			}
		}
	}
	
	//中序遍历
	//递归
	public void inOrderTravel(Node root){
		if(root==null){
			return;
		}
		inOrderTravel(root.left);
		System.out.print(root.val+" ");
		inOrderTravel(root.right);
	}
	//中序遍历迭代解法 ,用栈先把根节点的所有左孩子都添加到栈内, 
    // 然后输出栈顶元素,再处理栈顶元素的右子树 
	//迭代
	public void inOrderTravel2(Node root){
		if(root==null){
			return;
		}
		Stack<Node> stack=new Stack<Node>();
		Node cur=root;
		while(true){
			while(cur!=null){
				stack.push(cur);
				cur=cur.left;
			}
			if(stack.isEmpty()){
				break;
			}
			cur=stack.pop();
			System.out.print(cur.val+" ");
			cur=cur.right;
		}		
	}	
	
	//后序遍历
	//递归
	public void postOrderTravel(Node root){
		if(root==null){
			return;
		}
		postOrderTravel(root.left);
		postOrderTravel(root.right);
		System.out.print(root.val+" ");
	}
	//迭代
	//第二个stack用来翻转第一个stack
	public void postOrderTravel2(Node root){
		if(root==null){
			return;
		}
		Stack<Node> stack=new Stack<Node>();
		Stack<Node> outStack=new Stack<Node>();
		stack.push(root);
		while(!stack.isEmpty()){
			Node cur=stack.pop();
			outStack.push(cur);
			if(cur.left!=null){
				stack.push(cur.left);
			}
			if(cur.right!=null){
				stack.push(cur.right);
			}
		}
		while(!outStack.isEmpty()){
			System.out.print(outStack.pop().val+" ");
		}
	}
	

	//======求二叉树深度================================================
	//递归
	public int getDepth(Node root){
		if(root==null){
			return 0;
		}
		int ldep=getDepth(root.left);
		int rdep=getDepth(root.right);
		return Math.max(ldep, rdep)+1;
	}
	//迭代
	public int getDepth2(Node root){
		if(root==null)
			return 0;
		int depth=0;
		int currentnum=1;
		int nextnum=0;
		Queue<Node> queue=new LinkedList<Node>();
		queue.add(root);
		while(!queue.isEmpty()){
			Node cur=queue.remove();
			currentnum--;
			if(cur.left!=null){
				queue.add(cur.left);
				nextnum++;
			}
			if(cur.right!=null){
				queue.add(cur.right);
				nextnum++;
			}
			if(currentnum==0){
				depth++;
				currentnum=nextnum;
				nextnum=0;
			}
		}
		return depth;
	}
	
	
	//======求某一节点的深度======================================
	//递归
	public int getLayor(Node root,int n,int l){
		if(root==null){
			return -1;
		}
		int i=-1;
		if(root.val==n){
			return l;
		}
		if((i=getLayor(root.left,n,l+1))!=-1){
			return i;
		}
		if((i=getLayor(root.right,n,l+1))!=-1){
			return i;
		}
		return i;
	}
	//迭代方法
	public int getLayor2(Node root,int n){
		int num=1;
		if(root.val==n){
			return 1;
		}
		Queue<Node> queue=new LinkedList<Node>();
		queue.add(root);
		Node cur=root;
		while(!queue.isEmpty()){
			cur=queue.remove();
			if(cur.left!=null){
				queue.add(cur.left);
				cur.left.parent=cur;
				if(cur.left.val==n)
					break;
			}
			if(cur.right!=null){
				queue.add(cur.right);
				cur.right.parent=cur;
				if(cur.right.val==n)
					break;
			}
		}
		while(cur.parent!=null){
			cur=cur.parent;
			num++;
		}
		return num+1;
	}
	
	//======求二叉树节点个数================================================
	//递归方法
	public int nodeNum(Node root){
		if(root==null){
			return 0;
		}
		else{
			return(nodeNum(root.left)+nodeNum(root.right)+1);
		}
	}
	//迭代方法
	public int nodeNum2(Node root){
		if(root==null){
			return 0;
		}
		int num=1;
		ArrayList<Node> al=new ArrayList<Node>();
		al.add(root);
		while(!al.isEmpty()){
			if(al.get(0).left!=null){
				al.add(al.get(0).left);
				num++;
			}
			if(al.get(0).right!=null){
				al.add(al.get(0).right);
				num++;
			}
			al.remove(0);
		}
		return num;
	}
	
	//======以下求二叉树最大路径和============================================
	//max为每次递归之后的最大路径和
	private int max;
	//travel函数递归执行子树并求子树的最大路径
	private int travel(Node node){
		int val=node.val;
		//lval,rval分别为左子树和右子树的最大路径值
		int lval=0,rval=0;
		//result是可以返回给上一级树的路径值
		int result=val;
		/*
		 * 每次的travel函数中max是该级子树的最大路径值(该级子树最大路径值并不一定可以返回给上一级)
		 * 只有val,val+lval,val+rval其中之一才可以返回给上一级
		 * 关键的是,max用来保存所有子树的最大路径值
		 */
		//逐级寻找应该返回到上一级的result和当前最大max
		if(node.left!=null){
			lval=travel(node.left);
			if(lval>0){
				result=val+lval;
			}
			if(max<lval){
				max=lval;
			}
		}		
		if(node.right!=null){
			rval=travel(node.right);
			if(result<val+rval){
				result=val+rval;
			}
			if(max<rval){
				max=rval;
			}
		}
		if(max<result){
			max=result;
		}
		if(max<val+lval+rval){
			max=val+lval+rval;
		}
		return result;
	}
	public int maxPathSum(Node root){
		max=Integer.MIN_VALUE;
		travel(root);
		return max;
	}
}

//节点类
class Node{
	int val;
	Node left;
	Node right;
	Node parent;
	public Node(int x){
		this.val=x;
	}
}



运行结果:

总节点数为:9
最大路径和为:30
2在第3层
2在第3层
总深度为:4和4
前序遍历结果:3 5 1 2 4 7 6 9 8 
前序遍历结果:3 5 1 2 4 7 6 9 8 
中序遍历结果:1 5 2 3 6 7 9 4 8 
中序遍历结果:1 5 2 3 6 7 9 4 8 
后序遍历结果:1 2 5 6 9 7 8 4 3 
后序遍历结果:1 2 5 6 9 7 8 4 3 
分层遍历二叉树:3 5 4 1 2 7 8 6 9 
分层遍历二叉树:3 5 4 1 2 7 8 6 9 
转换为双向链表:1 5 2 3 6 7 9 4 8 




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值