二叉树的建立(通过前序遍历的数据序列反向生成二叉树);递归实现前序、中序、后序遍历;获取二叉树的节点数;求二叉树的深度

public class BinaryTree {
	 
	private TreeNode root=null;  //根节点;
	
	public BinaryTree(){
		root=new TreeNode(1,"A");   //初始化下标为1的根节点
	}
	
	/*
	 * 构建二叉树    -->把子节点一个个的加上去
	 * 			A
	 * 		B		C
	 *    D   E   	   F  
	 */
	public void createBinaryTree(){   
		TreeNode nodeB=new TreeNode(2,"B");
		TreeNode nodeC=new TreeNode(3,"C");
		TreeNode nodeD=new TreeNode(4,"D");
		TreeNode nodeE=new TreeNode(5,"E");
		TreeNode nodeF=new TreeNode(6,"F");
		
		root.leftChild=nodeB;
		root.rightChild=nodeC;
		nodeB.leftChild=nodeD;
		nodeB.rightChild=nodeE;
		nodeC.rightChild=nodeF;
	}
	
	/*
	 * 求二叉树的深度       简单举例:    A
	 * 					   B       C
	 * 							 D        此举例深度为3
	 */
	public int getHeight(){
		return getHeight(root);
	}	
	private int getHeight(TreeNode root2) {
		if(root2 == null){
			return 0;
		}
		else{            //迭代,每迭代一层,  表达式 getHeight(root2.leftChild)+1
			int i = getHeight(root2.leftChild);
			int j = getHeight(root2.rightChild);
			
			return (i < j) ? j+1 : i+1;
		}

	}
	
	/*
	 * 获取二叉树的节点数 举例:            A
	 * 				   			  B    C
	 */
	public int getSize(){
		return getSize(root);
	}
	private int getSize(TreeNode root2) {
		if(root2 == null){
			return 0;
		}
		else{
			return 1 + getSize(root2.leftChild) + getSize(root2.rightChild);
		}
	}

	/*
	 * 二叉树的前序遍历(根->左 ->右) -- 迭代实现     
	 */
	public void preOrder(TreeNode node){
		if(node == null){
			return;
		}
		else{
			System.out.println("preOrder data: "+node.getData());
			preOrder(node.leftChild);
			preOrder(node.rightChild);
		}
	}
	
	/*
	 * 
	 * 					  A
	 * 			B					C
	 * 		D		E			#	    F
	 * 	  #  #    #   #               #   #
	 * 
	 * 前序遍历: A B D # # E # # C # F # #
	 */
	
	/*
	 * 前序遍历  --非递归实现    核心思想: 每一次遍历 都记住他的根节点   压入子节点  弹出根节点
	 * 注:把B节点(包括下面的)那一坨遍历完之后,由于我们还记得之前有个根节点叫A,我们把那一坨当做一个大节点
	 * 把C当做右节点,把A当做根节点,因此把B那一大坨遍历完后还要找C节点(A的右节点)
	 * 同样地,当遍历至B节点,D节点遍历结束后,你为啥去遍历E节点呢? 是因为你还记得有个根节点B存在
	 */
	public void nonRecOrder(TreeNode node){
		if(node == null){
			return;
		}
		Stack<TreeNode> stack=new Stack<TreeNode>();
		stack.push(node);       //先压入根节点
		
		while( !stack.isEmpty()){
			//出栈和入栈
			TreeNode n=stack.pop();    //弹出根节点
			System.out.println("nonReOrder data: "+n.getData());
			//压入子节点
			if(n.rightChild != null){
				stack.push(n.rightChild);
			}
			if(n.leftChild != null){
				stack.push(n.leftChild);
			}			
		}
	}
	
	
	/*
	 * 二叉树的中序遍历   左->根->右
	 */
	public void midOrder(TreeNode node){
		if(node == null){
			return;
		}
		else{
			midOrder(node.leftChild);
			System.out.println("midOrder data: "+node.data);
			midOrder(node.rightChild);
		}
	}
	
	
	/**
	 * 迭代实现,首先依次将左子节点全部加入栈中,所以第一个while循环后栈顶元素对应一个子树的最
	 * 左子节点,然后将该元素出栈加入list,并判断该元素的遍历该节点的右子树。
	 */
	 //中序遍历的非递归实现    
    public void nonRecInOrder(TreeNode p){    
        Stack<TreeNode> stack =new Stack<TreeNode>();    
        TreeNode node =p;    
        while(node!=null || stack.size()>0){    
            //存在左子树    
            while(node!=null){    
                stack.push(node);    
                node=node.leftChild;    
            }    
            //栈非空    
            if(stack.size()>0){    
                node=stack.pop();    
                System.out.println("nonReOrder data: "+node.getData());    
                node=node.rightChild;    
            }    
        }    
    }    
	
	
	
	/*
	 * 二叉树的后序遍历   左->右->根
	 */
	public void postOrder(TreeNode node){
		if(node == null){
			return;
		}
		else{
			postOrder(node.leftChild);
			postOrder(node.rightChild);
			System.out.println("postOrder data: "+node.data);
		}
	}

	
	/**
	 * 使用栈实现,出栈得到节点顺序为根右左,每次向list最开头插入元素
	 * 				A
	 * 			B		C	
	 */
	public List<String> postOrderTraversal(TreeNode root) {
		List<String> result = new ArrayList<String>();
		if(root == null)
			return result;
		Stack<TreeNode> stack = new Stack<TreeNode>();
		stack.push(root);   //首先将根节点压栈
		while(!stack.isEmpty()) {
			TreeNode ele = stack.pop(); //首先出栈的为根节点,其后先出右子节点,后出左子节点
			if(ele.leftChild != null)
				stack.push(ele.leftChild);  //将左子节点压栈
			if(ele.rightChild != null) {
				stack.push(ele.rightChild); //将右子节点压栈
			}
			result.add(0,ele.data); //因为出栈顺序为“根右左”,所以需要每次将元素插入list开头
		}
		return result;
	}

	
	
	public class TreeNode{       //树节点
		private int index;
		private String data;
		private TreeNode leftChild;
		private TreeNode rightChild;
		
		public TreeNode(int index,String data){ //构造方法
			this.index=index;
			this.data=data;
			this.leftChild=null;
			this.rightChild=null;
		}
		
		public String getData() {
			return data;
		}
		public void setData(String data) {
			this.data = data;
		}
		public int getIndex() {
			return index;
		}
		public void setIndex(int index) {
			this.index = index;
		}
		public TreeNode getLeftChild() {
			return leftChild;
		}
		public void setLeftChild(TreeNode leftChild) {
			this.leftChild = leftChild;
		}
		public TreeNode getRightChild() {
			return rightChild;
		}
		public void setRightChild(TreeNode rightChild) {
			this.rightChild = rightChild;
		}
		
		
	}

	
	public static void main(String[] args) {
		BinaryTree binaryTree=new BinaryTree();
		binaryTree.createBinaryTree();
		
		int height=binaryTree.getHeight();
		System.out.println("treeHeight: "+height);
		
		//节点数
		int size=binaryTree.getSize();
		System.out.println("treeSize: "+size);
		
		//binaryTree.preOrder(binaryTree.root);     //前序遍历   递归:
		//System.out.println("******************");
		
		//binaryTree.midOrder(binaryTree.root);    //中序遍历     递归
		//System.out.println("*************");
		
		binaryTree.postOrder(binaryTree.root);     //后序遍历   递归
		//System.out.println("*********");
		
		//前序遍历  非迭代实现
		//binaryTree.nonRecOrder(binaryTree.root);  
		
		//中序遍历   非递归实现
		//binaryTree.nonRecInOrder(binaryTree.root);
		
		//后续  遍历    非递归实现
		//System.out.println(binaryTree.postOrderTraversal(binaryTree.root));
	}
	
				/*    2. 二叉树的建立   */
	/*
	 * 通过前序遍历的数据序列反向生成二叉树
	 * 					  A
	 * 			B					C
	 * 		D		E			#	    F
	 * 	  #  #    #   #               #   #
	 * 
	 * 前序遍历: A B D # # E # # C # F # #
	 */
	public void createBinaryTreePre(ArrayList<String> data){
		createBinaryTree(data.size(),data);
	}

	private TreeNode createBinaryTree(int size, ArrayList<String> data) {	
		if(data.size() == 0){
			return null;
		}
		String d=data.get(0);
		TreeNode node;
		int index= size - data.size();		
		
		if(d.equals("#")){
			node=null;
			return node;
		}
		node=new TreeNode(index,d);
		if(index == 0){
			//创建根节点
			root=node;
			data.remove(0);//每创建一个节点就去除头结点
		}else{
			data.remove(0);
			node.leftChild = createBinaryTree(size,data);
			node.rightChild= createBinaryTree(size,data);
		}
		return node;
	}
	
	
}

另一种二叉树的建立:

	public static void main(String[] args) {
		CreateBinaryTree binaryTree=new CreateBinaryTree();
		ArrayList<String> data=new ArrayList<>();
		String[] dataArray=new String[]{"A","B","D","#","#","E",
				"#","#","C","#","F","#","#"};
		for(String d: dataArray){
			data.add(d);
		}
		binaryTree.createBinaryTreePre(data);
	}

	/*    2. 二叉树的建立   */
	/*
	 * 通过前序遍历的数据序列反向生成二叉树
	 * 					  A
	 * 			B					C
	 * 		D		E			#	    F
	 * 	  #  #    #   #               #   #
	 * 
	 * 前序遍历: A B D # # E # # C # F # #
	 * 		   0 1 2 3 4 5 6 7 .....   12
	 */
	public void createBinaryTreePre(ArrayList<String> data){
		createBinaryTree(data.size(),data);
	}

	/*		A
	 * 	 #     B
	 */
	private TreeNode createBinaryTree(int size, ArrayList<String> data) {	
		if(data.size() == 0){	
			return null;
		}
		String d=data.get(0);
		TreeNode node;
		int index= size - data.size();		
		
		if(d.equals("#")){
			node=null;
			data.remove(0);   //即使是井号也要remove掉,因为它也占一个长度
			return node;
		}
		node=new TreeNode(index,d);
		if(index == 0){
			//创建根节点
			root=node;
		}
		data.remove(0);
		node.leftChild = createBinaryTree(size,data);
		node.rightChild= createBinaryTree(size,data);
		
		return node;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值