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

2024-02-23 08:58

本文主要是介绍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!=nullif(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 nodeif(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*/

 



这篇关于java 二叉树(十)前九篇二叉树的综合测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/738101

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定