java 二叉树(十)前九篇二叉树的综合测试

共有三个类:

结构体:Object(仅存放数据)

树类:Tree

测试类:Test

Object:

package 二叉树;

public class Object {
	public int value;
}

Tree:

package 二叉树;

public class Tree {
	public Node root;	//根节点
	//public Node left;	//指向左孩子节点的引用
	//public Node right;	//指向右孩子节点的引用
	
	public Tree(){
		root=null;
	}
	//
	public boolean isEmpty(){
		if(root==null){
			return true;
		}
		return false;
	}
	//递归创建二叉树
	Node Root;
	public void addTree(Object obj){
		if(isEmpty()){
			root=new Node(obj);
			System.out.println("root:"+root.data.value);	
			root.leftChild=null;
			root.rightChild=null;			
			Root=root;
		}else{
			if(obj.value<Root.data.value){
				if(Root.getLeftChild()!=null){
					if(Root.getLeftChild().data.value==obj.value){
						System.out.println("已存在"+Root.data.value+"请换值添加");
					}else{
						Root=Root.getLeftChild();
						System.out.println("root:"+Root.data.value);
						addTree(obj);
					}
				}else{
					Root.setLeftChild(new Node(obj));
					System.out.println("左	:"+Root.getLeftChild().data.value);
					Root=root;
				}
			}else if(obj.value>Root.data.value){
				if(Root.getRightChild()!=null){
					if(Root.getRightChild().data.value==obj.hashCode()){
						System.out.println("已存在"+Root.data.value+"请换值添加");
					}else{
						Root=Root.getRightChild();
						System.out.println("root:"+Root.data.value);
						addTree(obj);
					}
				}else{
					Root.setRightChild(new Node(obj));
					System.out.println("右	:"+Root.getRightChild().data.value);
					Root=root;
				}
			}else{
				System.out.println("已存在"+Root.data.value+"请换值添加");
			}
		}
	}
	//普通方式创建二叉树
	public void addTreeNode(Object obj){
		Node node = new Node(obj);
		Node temp;
		Node left;
		Node right;
		if(isEmpty()){
			root=node;
			System.out.println("root:"+root.data.value);	
			root.leftChild=null;
			root.rightChild=null;
		}else{
			temp = root;
			while(true){	//temp.leftChild!=null||temp.rightChild!=null
				if(node.data.value<temp.data.value){	//左
					if(temp.leftChild!=null){
						left = temp.getLeftChild();
						if(node.data.value==left.data.value){						
							System.out.println("已存在"+node.data.value+"请换值添加");
							break;												
						}
						temp = left;
						System.out.println("root:"+temp.data.value);
					}else{
						temp.setLeftChild(node);
						System.out.println("左	:"+temp.getLeftChild().data.value);
						break;												
					}
				}else if(node.data.value>temp.data.value){	//右
					if(temp.rightChild!=null){
						right = temp.getRightChild();
						if(node.data.value==right.data.value){
							System.out.println("已存在"+node.data.value+"请换值添加");
							break;												
						}
						temp=right;
						System.out.println("root:"+temp.data.value);
					}else{
						temp.setRightChild(node);
						System.out.println("右	:"+temp.getRightChild().data.value);						
						break;
					}
				}else{
					System.out.println("已存在"+node.data.value+"请换值添加");
					break;					
				}
			}
		}
	}
	//二叉树的遍历:先序遍历
	
	public void preOrder(Node temp){
		if(temp!=null){
			System.out.println("--先序--"+temp.data.value);
			preOrder(temp.getLeftChild());
			preOrder(temp.getRightChild());
		}
	}
	//二叉树的:中序遍历
	public void inOrder(Node temp){
		if(temp!=null){
			inOrder(temp.getLeftChild());
			System.out.println("--中序--"+temp.data.value);
			inOrder(temp.getRightChild());
		}
	}
	//二叉树的:后序遍历
	public void postOrder(Node temp){
		if(temp!=null){
			postOrder(temp.getLeftChild());
			postOrder(temp.getRightChild());
			System.out.println("--后序--"+temp.data.value);
		}
	}
	//求二叉树的层数
	public int hight(Node node){
		if(node==null){
			return 0;
		}else{
			int i=hight(node.getLeftChild());
			int j=hight(node.getRightChild());
			return (i<j)?(j+1):(i+1);
		}
	}
	//求二叉树的节点数
	public int sumNode(Node node){
		if(node==null){
			return 0;
		}else{
			int a=sumNode(node.getLeftChild());
			int b=sumNode(node.getRightChild());
			return 1+a+b;
		}
	}
	//求二叉树中一个节点的父节点,双亲结点
	public Node parent(Object obj){
		Node temp=parent(root, obj);
		return temp;
	}
	public Node parent(Node node, Object findnode){
		if(node==null){
			return null;
		}
		if((node.getLeftChild()!=null&&node.getLeftChild().data.value==findnode.value)||(node.getRightChild()!=null&&node.getRightChild().data.value==findnode.value)){
			//如果找到返回双亲节点
			//这里需要判断node的左或右孩子是否为空的条件,否则一旦node的左孩子或右孩子为空(即:找不到)会报空指针的错误
			return node;
		}
		
		//在左子树中查找 , 如果左子树中没有去右子树中查找
		Node N;
		if((N=parent(node.getLeftChild(),findnode))!=null){
			return N;
		}else{
			return parent(node.getRightChild(),findnode);
		}
	}
	//查找节点
	public Node findNode(Object obj){
		Node node = new Node(obj);
		if(root==null){
			System.out.println("树中没有你要查找的值!");
			return null;
		}else{
			Node temp=findNode(root,node);
				return temp; 				
			
		}
		 
	}
	public Node findNode(Node roo,Node node){
		if(roo==null){
			return null;
		}
		if(roo.data.value==node.data.value){
			return roo;
		}
		Node N;
		Node P;
		if((N=findNode(roo.getLeftChild(),node))!=null){
			
			return N;
		}else{
			roo=roo.getRightChild();
			if((P=findNode(roo,node))==null){
				return null;
			}else{
				return P;				
			}
		}
	}
	//删除树中的一个节点,用被删除节点的孩子补上,不能破坏二叉树的排序规律:左孩子始终小于右孩子
	public void delSort(Object obj){
		Node temp;
		Node node=parent(obj);
		

		if((temp=findNode(obj))!=null){
			//如果删除的是根节点,就让其左子树的最大值放在根节点
			if(root.data.value==temp.data.value){
				Node node1=delFind(temp.getLeftChild());
				node1.setLeftChild(root.getLeftChild().getLeftChild());
				node1.setRightChild(root.getRightChild());
				root=node1;
				
			}else{
			if(temp.getLeftChild()==null&&temp.getRightChild()==null){
				//如果要删除的节点没有左和右孩子,则找到被删除节点的父节点,让其父节点的左孩子指向或右孩子指向置空,即删除
				if(node.data.value<obj.value){//要删除节点是父节点的右孩子
					node.setRightChild(null);//置空删除右孩子
				}else if(node.data.value>obj.value){//要删除节点是父节点的左孩子
					node.setLeftChild(null);//置空删除
				}
			}else if(temp.getLeftChild()!=null&&temp.getRightChild()!=null){
				/*
				 * 若左右孩子都不为空,则从要删除节点的右子树上取最小值放到被删除节点上即可,并把右子树上的最小值删除
				 * 			Q
				 *         /
				 * 		  E 
				 * 		 / \
				 * 		A   F
				 *     / \
				 *    D   B
				 * 	      /
				 * 	     C
				 * 此时若删除E,则首先找到E的父节点Q和E的所有子孙中的最大节点B,
				 * 然后让Q指向B,B的左孩子指向A,B的右孩子指向F,最后把E置空释放空间;
				 * 
				 * 			Q
				 *         /
				 * 		  B 
				 * 		 / \
				 * 		A   F
				 *     / \
				 *    D   C
				 * 	 E=null 释放掉      
				 * 	     
				 * 
				 */
				Node node1=delFind(temp.getLeftChild());
				if(node.data.value<obj.value){//要删除节点是父节点的右孩子
					
					//取被删除节点的左孩子中的最大值,让父节点的右孩子指向被删除节点的左孩子中的最大值;若被删除节点的左孩子中的最大值等于被删除节点的左孩子的值 则让父节点的右孩子指向被删除节点的左孩子
					if(temp.getLeftChild().data.value==node1.data.value){
						node.setRightChild(temp.getLeftChild());
						temp.getLeftChild().setRightChild(temp.getRightChild());
						temp=null;
					}else{
						node.setRightChild(node1);
						node1.setLeftChild(temp.getLeftChild());
						node1.setRightChild(temp.getRightChild());
						temp=null;						
					}
				}else if(node.data.value>obj.value){//要删除节点是父节点的左孩子
					if(temp.getLeftChild().data.value==node1.data.value){
						node.setLeftChild(temp.getLeftChild());
						temp.getLeftChild().setRightChild(temp.getRightChild());
						temp=null;
					}else{
						node.setLeftChild(node1);
						node1.setLeftChild(temp.getLeftChild());
						node1.setRightChild(temp.getRightChild());
						temp=null;						
					}	
				}

				
			}else if(temp.getLeftChild()!=null&&temp.getRightChild()==null){//左孩子不为空右孩子为空的情况,则把要删除节点的左孩子放到被删除节点上即可																	
				if(node.data.value<obj.value){//要删除节点是父节点的右孩子					
					node.setRightChild(temp.getLeftChild());//要删除节点的父节点的右孩子指向为被删除节点的左孩子,并把被删除节点的左指向置空,即删除
					temp=null;
				}else if(node.data.value>obj.value){//要删除节点是父节点的左孩子
					node.setLeftChild(temp.getLeftChild());
					temp=null;					
				}
			}else if(temp.getLeftChild()==null&&temp.getRightChild()!=null){
				//左孩子为空右孩子不为空的情况,则把要删除节点的右孩子放到被删除节点上即可
				if(node.data.value<obj.value){//要删除节点是父节点的右孩子					
					node.setRightChild(temp.getRightChild());//要删除节点的父节点的右孩子指向为被删除节点的左孩子,并把被删除节点的左指向置空,即删除
					temp=null;//删除之后置空,释放空间
				}else if(node.data.value>obj.value){//要删除节点是父节点的左孩子
					node.setLeftChild(temp.getRightChild());
					temp=null;					
				}
				
			}
			}	
		}else{
			System.out.println("你需要删除的节点不存在!");
			//return false;
		}
	}
	//查找一个节点下所有子孙中的最大值,并且删除这个节点,
	public Node delFind(Node node){	//传入参数为被删除节点的左孩子Node node
		//Node temp=node;
		if(node.getRightChild()==null){
			return node;
		}
		if(node.getRightChild().getRightChild()==null){
			if(node.getRightChild().getLeftChild()!=null){
				/*
				 * 如果被删除的节点有有左孩子,需要用被删除节点的父节点的右孩子指向被删除结点的左孩子,
				 * 然后再把被删除节点的左孩子指向设为null,那么需要删除的节点就被删掉了
				 * 意思就是把B删除,把A指向C
				 * 		A
				 *     / \
				 *    D   B
				 * 	      /
				 * 	     C
				 */
				Node temp=node.getRightChild();
				node.setRightChild(node.getRightChild().getLeftChild());
				//node.getRightChild().setLeftChild(null);
				temp.setLeftChild(null);
				return  temp;
			}
			Node temp=node.getRightChild();
			node.setRightChild(null);
			return temp;
		}
		
		return delFind(node.getRightChild());
	}
	//获取右子树中的最小节点
	public Node minRightNode(Node node){//传入参数为被删除节点的右孩子Node node
		if(node.getLeftChild()==null){
			return null;
		}
		if(node.getLeftChild().getLeftChild()==null){
			if(node.getLeftChild().getRightChild()!=null){
				/*
				 * 如果被删除的节点有右孩子,需要用被删除节点的父节点的左孩子指向被删除结点的右孩子,
				 * 然后再把被删除节点的右孩子指向设为null,那么需要删除的节点就被删掉了
				 * 意思就是把    D  删除,把A指向C
				 * 		A
				 *     / \
				 *    D   B
				 * 	   \
				 * 	    C
				 */
				Node temp=node.getLeftChild();
				node.setLeftChild(node.getLeftChild().getRightChild());
				//node.getRightChild().setLeftChild(null);
				temp.setRightChild(null);
				return  temp;
			}
			Node temp=node.getLeftChild();
			node.setLeftChild(null);
			return temp;
		}
		
		return minRightNode(node.getLeftChild());
	}
	class Node {
		public Object data;	//数据区 节点存储的值
		public Node leftChild;	//指向左孩子节点的引用
		public Node rightChild;	//指向右孩子节点的引用
		public Node(Object value){
			this.data=value;
			leftChild = null;
			rightChild = null;
		}
		public Node(){
			
		}
		public void setData(Object data){
			this.data=data;
		}
		public Object getData(){
			return data;
		}
		public void setLeftChild(Node node){
			this.leftChild=node;
		}
		public Node getLeftChild(){
			return leftChild;
		}
		public void setRightChild(Node node){
			this.rightChild=node;
		}
		public Node getRightChild(){
			return rightChild;
		}
	}
	
}

测试类:Test

package 二叉树;

public class Test {
	public static void main(String[] args){
		Tree tree = new Tree();
		Object[] obj = new Object[5];
		Object a= new Object();
		a.value=10;
		Object a1= new Object();
		a1.value=8;
		Object a2= new Object();
		a2.value=5;
		Object a3= new Object();
		a3.value=4;
		Object a4= new Object();
		a4.value=6;
		Object a5= new Object();
		a5.value=7;
		Object a6= new Object();
		a6.value=9;
		Object a7= new Object();
		a7.value=11;
		Object a12= new Object();
		a12.value=12;
		tree.addTree(a);
		tree.addTree(a1);
		tree.addTree(a2);
		tree.addTree(a3);
		tree.addTree(a4);
		tree.addTree(a5);
		tree.addTree(a6);
		tree.addTree(a7);
		System.out.println("--------先序--------");
		tree.preOrder(tree.root);
		System.out.println("--------中序--------");
		tree.inOrder(tree.root);
		System.out.println("--------后序--------");
		tree.postOrder(tree.root);
		System.out.println("树的高度:"+tree.hight(tree.root));
		System.out.println("树的节点总数:"+tree.sumNode(tree.root));
		System.out.println("寻找一个节点的双亲节点:"+tree.parent(tree.root, a4).data.value);
		if(tree.findNode(a7)==null){
			System.out.println("树中没有你要查找的值!");
		}else{
			System.out.println("查找到一个节点:"+a7.value);			
		}
		System.out.println("-----删除节点-----");
		tree.delSort(a1);
		tree.preOrder(tree.root);
		
		
	}
}
/*	普通法添加节点 
tree.addTreeNode(a);
tree.addTreeNode(a1);
tree.addTreeNode(a2);
tree.addTreeNode(a3);
tree.addTreeNode(a5);
tree.addTreeNode(a6);
tree.addTreeNode(a4);*/<pre name="code" class="java">/*测试结果:
测试结果:
root:10
左	:8
root:8
左	:5
root:8
root:5
左	:4
root:8
root:5
右	:6
root:8
root:5
root:6
右	:7
root:8
右	:9
右	:11
--------先序--------
--先序--10
--先序--8
--先序--5
--先序--4
--先序--6
--先序--7
--先序--9
--先序--11
--------中序--------
--中序--4
--中序--5
--中序--6
--中序--7
--中序--8
--中序--9
--中序--10
--中序--11
--------后序--------
--后序--4
--后序--7
--后序--6
--后序--5
--后序--9
--后序--8
--后序--11
--后序--10
树的高度:5
树的节点总数:8
寻找一个节点的双亲节点:5
查找到一个节点:11
-----删除节点-----
--先序--10
--先序--7
--先序--5
--先序--4
--先序--6
--先序--9
--先序--11

*/

 



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值