java 二叉树 实现 数据结构 笔试

笔试常考数据结构,所以最近复习了一下数据结构,今天复习到了二叉树,所以写一下笔记。

顺便做了一下测试,参考了网上的一些例子~~~


实现了:二叉树的创建,二叉树的遍历(递归与非递归),求二叉树深度,判断是否为完全二叉树


不说了,直接上代码。

结构大概这样:


最主要的的类:

package binaryTreeTest;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/** 
 * @author  5354xyz
 * @version 2014-5-4 下午5:27:10 
 * @E5354xyz-mail: xiaoyizong@126.com
 */
public class BinaryTree {
	
	 public String nodevalue;   
     public BinaryTree leftchild, rightchild;  
     private Visit onVisitListener ;
     public BinaryTree()   
     { }   
     public BinaryTree(String value)   
     {   
         nodevalue = value;   
     }  
     public void setVisitListener(Visit onVisitListener)
     {
    	 this.onVisitListener = onVisitListener;
     }
     public void assignchild(BinaryTree left, BinaryTree right)//设定左右孩子   
     {   
         this.leftchild = left;   
         this.rightchild = right;   
     }  

     public boolean hasleftchild()//是否有左孩子   
     {   
        
             return (this.leftchild != null);   
          
     }  

     public boolean hasrightchild()//是否有右孩子   
     {   
         
             return (this.rightchild != null);   
           
     }  

     public boolean haschild()//是否有孩子   
     {   
          
             return hasleftchild() || hasrightchild();   
          
     } 
     
   /**
    * 计算深度   
    * 2014-5-4
    * 
    * @author:5354xyz
    */
     public int maxDepth(BinaryTree root)   
     {   
         if (root == null)   
         {   
             return 0;   
         }   
         else   
         {   
             int leftdepth = maxDepth(root.leftchild);//递归计算左孩子的深度   
             int rightdepth = maxDepth(root.rightchild);//递归计算右孩子的深度  

             if (leftdepth >= rightdepth)   
             {   
                 return leftdepth + 1;   
             }   
             else   
             {   
                 return rightdepth + 1;   
             }   
         }   
     }
     
     /**
      * 计算节点数
      * 2014-5-4
      * 
      * @author:5354xyz
      */
     public int count(BinaryTree subTree){  
         if(subTree==null){  
             return 0;  
         }else{  
             return 1+count(subTree.leftchild)  
                     +count(subTree.rightchild);  
         }  
     }
     
     /**
      * 求二叉树第K层的节点个数
      * 2014-5-4
      * 
      * @author:5354xyz
      */
     int GetNodeNumKthLevel(BinaryTree pRoot, int k)  
     {  
         if(pRoot == null || k < 1)  
             return 0;  
         if(k == 1)  
             return 1;  
         int numLeft = GetNodeNumKthLevel(pRoot.leftchild, k-1); // 左子树中k-1层的节点个数  
         int numRight = GetNodeNumKthLevel(pRoot.rightchild, k-1); // 右子树中k-1层的节点个数  
         return (numLeft + numRight);  
     }
     
   /**
    * 前序遍历  
    * 2014-5-4
    * 
    * @author:5354xyz
    */
     public void preOrder(BinaryTree subTree){  
         if(subTree!=null){  
        	 onVisitListener.visit(subTree);  
             preOrder(subTree.leftchild);  
             preOrder(subTree.rightchild);  
         }  
     }  
       
     /**
      * 中序遍历  
      * 2014-5-4
      * 
      * @author:5354xyz
      */
     public void inOrder(BinaryTree subTree){  
         if(subTree!=null){  
             inOrder(subTree.leftchild);  
             onVisitListener.visit(subTree);   
             inOrder(subTree.rightchild);  
         }  
     }  
       
     /**
      * 后续遍历  
      * 2014-5-4
      * 
      * @author:5354xyz
      */
     public void postOrder(BinaryTree subTree) {  
         if (subTree != null) {  
             postOrder(subTree.leftchild);  
             postOrder(subTree.rightchild);  
             onVisitListener.visit(subTree);   
         }  
     }
     
   /**
    * 前序遍历的非递归实现  
    * 2014-5-4
    * 
    * @author:5354xyz
    */
     public void nonRecPreOrder(BinaryTree p){  
         Stack<BinaryTree> stack=new Stack<BinaryTree>();  
         if (p != null) {  
             stack.push(p);  
             while (!stack.empty()) {  
                 p = stack.pop();  
                 onVisitListener.visit(p); 
                 if (p.rightchild != null)  //先push,在栈底,实现了根左右
                     stack.push(p.rightchild);  
                 if (p.leftchild != null)  
                     stack.push(p.leftchild);  
             }  
         }   
     }  
     
     /** 
      * 非递归实现前序遍历2 */  
     public void nonRecPreOrder2(BinaryTree p){    
    	 Stack<BinaryTree> stack=new Stack<BinaryTree>();   
    	 BinaryTree node = p;  
         while (node != null || stack.size() > 0) {  
             while (node != null) {//压入所有的左节点,压入前访问它  
            	 onVisitListener.visit(node); 
                 stack.push(node);  
                 node = node.leftchild;  
             }  
             if (stack.size() > 0) {//  
                 node = stack.pop();  
                 node = node.rightchild;  
             }  
         }  
     } 
     /**
      * 中序遍历的非递归实现  
      * 2014-5-4
      * 
      * @author:5354xyz
      */
     public void nonRecInOrder(BinaryTree p){  
         Stack<BinaryTree> stack =new Stack<BinaryTree>();  
         BinaryTree node =p;  
         while(node!=null||stack.size()>0){  
             //存在左子树  
             while(node!=null){  
                 stack.push(node);  
                 node=node.leftchild;  
             }  
             //栈非空  
             if(stack.size()>0){  
                 node=stack.pop();  
                 onVisitListener.visit(node); 
                 node=node.rightchild;  
             }  
         }  
     }  
       
     //后序遍历的非递归实现  
     public void noRecPostOrder(BinaryTree p){  
         Stack<BinaryTree> stack=new Stack<BinaryTree>();  
         BinaryTree node =p;  
         while(p!=null){  
             //左子树入栈  
             for(;p.leftchild!=null;p=p.leftchild){  
                 stack.push(p);  
             }  
             //当前结点无右子树或右子树已经输出  
             while(p!=null&&(p.rightchild==null||p.rightchild==node)){  
            	 onVisitListener.visit(p);
                 //纪录上一个已输出结点  
                 node =p;  
                 if(stack.empty())  
                     return;  
                 p=stack.pop();  
             }  
             //处理右子树  
             stack.push(p);  
             p=p.rightchild;  
         }  
     }
     
     /**
      * 按层遍历二叉树
      * 2014-5-4
      * 
      * @author:5354xyz
      */
     public void levelTraverse(BinaryTree bTree)
     {  
         if(bTree == null )  
             return;  
         Queue<BinaryTree> queue = new LinkedList<BinaryTree>();  
         queue.offer(bTree);  
         while(!queue.isEmpty())  
         {  
        	 BinaryTree pNode = queue.poll();  
               
        	 onVisitListener.visit(pNode); // 访问节点  
             if(pNode.leftchild != null)  
            	 queue.offer(pNode.leftchild);  
             if(pNode.rightchild != null)  
            	 queue.offer(pNode.rightchild);  
         }  
         return;  
     } 
     /**
      * 判断二叉树是否为完全二叉树
      * 2014-5-4
      * 
      * @author:5354xyz
      */
     boolean IsCompleteBinaryTree(BinaryTree pRoot)  
     {  
         if(pRoot == null)  
             return false;  
         Queue<BinaryTree> q = new LinkedList<BinaryTree>();;  
         q.offer(pRoot);  
         boolean mustHaveNoChild = false;  
         boolean result = true;  
         while(!q.isEmpty())  
         {  
        	 BinaryTree pNode = q.poll();  
             if(mustHaveNoChild) // 已经出现了有空子树的节点了,后面出现的必须为叶节点(左右子树都为空)  
             {  
                 if(pNode.leftchild != null || pNode.rightchild != null)  
                 {  
                     result = false;  
                     break;  
                 }  
             }  
             else  
             {  
                 if(pNode.leftchild != null && pNode.rightchild != null)  
                 {  
                     q.offer(pNode.leftchild);  
                     q.offer(pNode.rightchild);  
                 }  
                 else if(pNode.leftchild != null && pNode.rightchild == null)  
                 {  
                     mustHaveNoChild = true;  
                     q.offer(pNode.leftchild);  
                 }  
                 else if(pNode.leftchild == null && pNode.rightchild != null)  
                 {  
                     result = false;  
                     break;  
                 }  
                 else  
                 {  
                     mustHaveNoChild = true;  
                 }  
             }  
         }  
         return result;  
     } 

}

测试程序:

package binaryTreeTest;
/** 
 * @author  5354xyz
 * @version 2014-5-4 下午5:26:20 
 * @E5354xyz-mail: xiaoyizong@126.com
 */
public class BinaryTreeTest implements Visit
{

	/**
	 * 2014-5-4
	 * 
	 * @author:5354xyz
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BinaryTree node_a = new BinaryTree("a");   
		BinaryTree node_b = new BinaryTree("b");   
		BinaryTree node_c = new BinaryTree("c");   
		BinaryTree node_d = new BinaryTree("d");   
		BinaryTree node_e = new BinaryTree("e");   
		BinaryTree node_f = new BinaryTree("f");   
		BinaryTree node_g = new BinaryTree("g");   
		BinaryTree node_h = new BinaryTree("h");   
		BinaryTree node_i = new BinaryTree("i");
		BinaryTree node_j = new BinaryTree("j");
        //构造一棵二叉树   
        node_a.assignchild(node_b, node_c);   
        node_b.assignchild(node_d, node_e);   
        node_c.assignchild(node_f, node_g);   
        node_e.assignchild(node_h, node_i);
        node_h.assignchild(node_j, null);
        
        /* 					A
         * 			B				C
         * 	    D  		 E   	F    	G
         * 			   H   I
         * 			 j
         * 
         */
        BinaryTreeTest binaryTreeTest =new BinaryTreeTest();
        node_a.setVisitListener(binaryTreeTest);
        //输出树的深度
        System.out.println("二叉树的深度:"+node_a.maxDepth(node_a));
        System.out.println("二叉树的总结点数:"+node_a.count(node_a));
        int ceng=4;
        System.out.println("二叉树的第"+ceng+"层结点数:"+node_a.GetNodeNumKthLevel(node_a,ceng));
        //这个跟
        System.out.println("是否是完全二叉树呢?"+node_a.IsCompleteBinaryTree(node_a));
        //先序遍历
        node_a.preOrder(node_a);
        System.out.print(" 递归|非递归     ");
        node_a.nonRecPreOrder(node_a);
        System.out.print(" 非递归 2 ");
        node_a.nonRecPreOrder2(node_a);
        System.out.println("先序遍历");
        //中序遍历
        node_a.inOrder(node_a);
        System.out.print(" 递归|非递归     ");
        node_a.nonRecInOrder(node_a);
        System.out.println("中序遍历");
        //后序遍历
        node_a.postOrder(node_a);
        System.out.print(" 递归|非递归     ");
        node_a.noRecPostOrder(node_a);
        System.out.println("后序遍历");
        //按层遍历
        node_a.levelTraverse(node_a);
        System.out.println("按层遍历");
        
	}

		@Override
		public void visit(BinaryTree binaryTreeNode) {
			// TODO Auto-generated method stub
			System.out.print(binaryTreeNode.nodevalue+" ");
		}
	
}
最后还有个访问的接口:

package binaryTreeTest;
/** 
 * @author  5354xyz
 * @version 2014-5-4 下午5:37:21 
 * @E5354xyz-mail: xiaoyizong@126.com
 */
public interface Visit {
	
	/**
	 * visit接口
	 */
	public void visit(BinaryTree binaryTreeNode);

}


测试的效果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值