package com.data.java.towtree;

import java.io.IOException;

/**
* 二叉树
* @Title: uminton
*/ class Node{
public int iData; //数据用作关键值
public double dData; //其他数据
public Node leftChild; //左子节点
public Node rightChild; //右子节点 public Node() {
} public Node(int iData, double dData) {
this.iData = iData;
this.dData = dData;
} public void displayNode(){
System.out.print("{");
System.out.print(iData);
System.out.print(", ");
System.out.print(dData);
System.out.print("} ");
}
} public class Tree { private Node root; //根节点 public Node getRoot() {
return root;
} /**
* 查找一个数据
* @param key
* @return
*/
public Node find(int key){
Node current = root; //把跟节点设置为当前节点
while (current.iData != key){ //循环查找
if(key < current.iData){ //如果小于就去当前树的左边子节点
current = current.leftChild; //把子节点赋给当前节点
}else { //如果大于就去当前树的右边子节点
current = current.rightChild;//把子节点赋给当前节点
}
if(current == null){ //到达序列的末端没有找到节点,表明他不存在,返回空
return current;
}
}
return current; //循环条件相等,循环结束,找到结果。
} /**
* 添加一个数据
* @param id
* @param dd
*/
public void insert(int id, double dd) {
Node newNode = new Node(id, dd); //先创建一个新节点
if(root == null){ //如果跟节点为空,表示树,没有数据,直接赋值给根节点
root = newNode;
}else {
Node current = root; //根节点赋值给当前节点,用于查找
Node parent; //父节点,用来存储遇到的最后一个不是null的节点,因为curent在查找的过程中会变成null,
// 才能发现发现查找过得上一个节点没有子节点
while (true){ //循环查找
parent = current; //用来存储遇到的最后一个不是null的节点
if (id < current.iData){ //如果小于就去当前树的左边子节点
current = current.leftChild;
if(current == null){ //到达序列的末端没有找到节点,表明他不存在
parent.leftChild = newNode; //把新的节点赋值给父节点的左子节点
return; //直接返回,结束循环
}
}else {
current = current.rightChild;
if(current == null){
parent.rightChild = newNode;
return;
}
}
}
}
} /**
* 删除一个数据
* @param key
* @return
*
* 删除节点要考虑的三种情况
* 1,该节点是叶节点
* 2,该节点有一个子节点
* 3,该节点有二个子节点
*/
public boolean delete(int key){
Node current = root;
Node parent = root;
boolean isLeftChild = true; //记录是左节点还是右节点
while(current.iData != key){ //循环为了找到要删除的节点,循环条件如果相等就是找到了,退出循环
parent = current; //保存要删除的父节点
if(key < current.iData){
isLeftChild = true;
current = current.leftChild;
}else {
isLeftChild = false;
current = current.rightChild;
}
if(current == null){ //查找到末端,都没有找到,返回false
return false;
}
}
/**************************情况1开始*********************************/
if(current.leftChild == null && current.rightChild == null) { //判断是否没有子节点,也就是该节点是叶节点
if (current == root) { //如果是根节点,直接赋值为null
root = null;
} else if (isLeftChild) { //判断是否是左节点
parent.leftChild = null; //用上面保存的父节点找子节点,直接赋值为null
} else {
parent.rightChild = null;
}
/**************************情况1结束*********************************/ /**************************情况2开始*********************************/
}else if (current.rightChild == null){ //判断左边等null或右边等于null
if(current == root){ //如果是根节点,直接赋值为null
root = current.leftChild;
}else if (isLeftChild){ //判断是否是左节点
parent.leftChild = current.leftChild;//用上面保存的父节点找子节点,直接赋值为null
}else {
parent.rightChild = current.leftChild;
}
}else if (current.leftChild == null){ //下面同理
if(current == root){
root = current.rightChild;
}else if (isLeftChild){
parent.leftChild = current.rightChild;
}else {
parent.rightChild = current.rightChild;
}
/**************************情况2结束*********************************/ /**************************情况3开始*********************************/
}else { //上面都不成立,表明该节点有两个子节点。
Node successor = getSuccessor(current); //取得后继者
if(current == root){ //如果是根节点,直接赋值为后继者
root = successor;
}else if (isLeftChild){ //判断是否是左节点
parent.leftChild = successor; //用上面保存的父节点找子节点,直接赋值为后继者
}else {
parent.rightChild = successor;
}
successor.leftChild = current.leftChild;
}
/**************************情况3结束*********************************/
return true;
} /**
* 中序遍历树
* @param localRoot
*/
public void inOrder(Node localRoot){
if(localRoot != null){
inOrder(localRoot.leftChild);
System.out.println(localRoot.iData);
inOrder(localRoot.rightChild);
}
} /**
* 查找最小值
* @return
*/
public Node minNumber(){
Node current = root;
Node last = null;
while (current != null){
last = current;
current = current.leftChild;
}
return last;
} /**
* 获取删除节点的后继者
* @param delNode
* @return
* 算法:程序找到要删除的节点的右子节点,(它的关键字值一定比要删除的节点的值大)然后转到右子节点的左子节点(若果有的话)
* 然后到这个左子节点的左子节点,以此类推,这个路径的最后一个左子节点就是要删除节点的后继者
* 若果删除节点右子节点没有左子节点,它就是后继者
*/
private Node getSuccessor(Node delNode) {
Node successorParent = delNode;
Node successor = delNode;
Node current = delNode.rightChild; //删除节点右子节点
while (current != null){
successorParent = successor; //保留后继者的父节点
successor = current; //后继者
current = current.leftChild; //循环查找左子节点
}
if(successor != delNode.rightChild){
successorParent.leftChild = successor.rightChild;
successor.rightChild = delNode.rightChild;
}
return successor;
}
} class TreeApp{
public static void main(String[] args) throws IOException {
Tree treTree = new Tree();
treTree.insert(38,1.5);
treTree.insert(65,1.5);
treTree.insert(40,1.5);
treTree.insert(50,1.5);
treTree.insert(55,1.5);
treTree.insert(30,1.5);
treTree.insert(90,1.5);
treTree.insert(25,1.6);
treTree.insert(70,1.7);
treTree.insert(20,1.7);
treTree.insert(80,1.7); treTree.delete(65); }
}

  

最后删除有点复杂,没怎么搞懂见谅。

java学习之—二叉树的更多相关文章

  1. java学习之二叉树的实现

    二叉树是一种数据结构,每个节点都有两个子节点. 二叉树的遍历有三种方式, 先序遍历是 根节点,左子树,右子树: 中序遍历是 左子树,根节点,右子树: 后序遍历是 左子树,右子树,根节点: java实现 ...

  2. java学习笔记13--比较器(Comparable、Comparator)

    java学习笔记13--比较器(Comparable.Comparator) 分类: JAVA 2013-05-20 23:20 3296人阅读 评论(0) 收藏 举报 Comparable接口的作用 ...

  3. Java学习需要掌握的一些知识

    Java学习需要掌握的一些知识: <一>1.Jvm 部分Jvm 内存模型.Jvm 内存结构.Jvm 参数调优.Java 垃圾回收<二>Java 基础部分1.必须会使用 List ...

  4. JAVA学习第二步,初级知识框架梳理

    回顾往期的学习,才发现已经学习了这么多知识点.这里复制了其他创作者的一些梳理结合自己的梳理.总结了自己在Java学习入门阶段的知识点.笔记自己了也写了详细的两本 第一章 Java面向对象 1-1包的定 ...

  5. 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁

    什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...

  6. 0035 Java学习笔记-注解

    什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...

  7. 分享篇——我的Java学习路线

    虽然之前我是开发出身,但是我学习的语言是Objective-c,这个语言使用起来范围比较窄,对于自动化学习来说也是无用武之地,所以我自己学习了Java,对于一个有开发经验的人来说学习一门新语言相对来说 ...

  8. Java学习笔记(04)

    Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...

  9. Java学习心得之 HttpClient的GET和POST请求

    作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Java学习心得之 HttpClient的GET和POST请求 1. 前言2. GET请求3 ...

随机推荐

  1. maven-1-是什么

    背景 1.1. 场景 假如你正在Eclipse下开发两个Java项目,姑且把它们称为A.B,其中A项目中的一些功能依赖于B项目中的某些类,那么如何维系这种依赖关系的呢? 很简单,这不就是跟我们之前写程 ...

  2. 从Myeclipse到IntelliJ IDEA-——让你摆脱鼠标,全键盘操作

    注:本文是对原文章(https://blog.csdn.net/luoweifu/article/details/13985835)做的补充 快捷键对比 Myeclipse IDEA 说明 Ctrl+ ...

  3. 自动化运维:(1)认识 Shell

    目录 (一)运维是什么? (二)什么是 Shell? (三)Shell的分类 (四)Shell脚本 (五)Shell的变量 (六)表达式 (七)Linux常见符号 (八)常见命令 (一)自动化运维是什 ...

  4. 深入理解C语言-二级指针三种内存模型

    二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {&quo ...

  5. 关于Npoi+excel文件读取,修改文件内容的处理方式

    因最近有需求场景,实现对文件的读写操作,又不单独生成新的文件,对于源文件的修改,做了一个简单实现,如下↓ // 要操作的excel文件路径 string fileName = Server.MapPa ...

  6. Linux第三阶段题型测试

    1.如何取得/etiantian文件的权限对应的数字内容,如-rw-r--r--为644,要求使用命令取得644或0644这样的数字. 解答: 1)最土的方法:ls -l /etiantian |cu ...

  7. 二分图的最大匹配以及带权匹配【匈牙利算法+KM算法】

    二分图算法包括 匈牙利算法 与 KM算法. 匈牙利算法 在这里写上模板. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2063 #include< ...

  8. PYTHON 100days学习笔记001:初识python

    现在学习这个确实时间很紧,但是迟早得学,以后PYTHON自动化运维,PYTHON自动测试都需要用的到,甚至可以往数据分析方向发展,刚好最近有数据观组织的python100天计划,就参加了,做好笔记,一 ...

  9. SpringBoot整合MyBatis完成用户查询

    接上面工程代码,可以参考:https://www.cnblogs.com/braveym/p/11349409.html 1 .在 mapper 接口中以及映射配置文件中添加相关代码 修改UserMa ...

  10. Centos删除多余的Linux内核

    删除开机多余kernel(centos) yum update 命令会大范围升级,有时候linux内核也会升级,升级后开机画面就会出现多个内核供你选择,所有强迫症的我需要删除旧的 ⒈查看正在使用的内核 ...