二叉树的实现

数组查询快,增删慢;链表增删快,查询慢;二叉树查询和增删都有很好的性能

package com.itheiam62;/*** @描述 中序遍历是有序的二叉树(不重复)* */
public class MyTree
{private Node    root;   // 根节点private class Node{Node    parrent;    // 父节点Node    left;       // 左儿子Node    right;      // 右儿子Object  data;public Node(Object data) {this.data = data;}}/*** @param data*            传递的数据* @return 父节点的值*/private Node findParrent(Object data, Node currentNode) {// 从根节点找Node temp = currentNode;Node parrent = currentNode;// 循环找while (temp != null) {parrent = temp;// 比较if (compare(data, temp.data)) {// data 大于 当前节点temp = temp.right;} else {// data 小于 当前节点temp = temp.left;}}return parrent;}public void update(Object oldData,Object newData){remove(oldData);add(newData);}/*** 添加数据* * @param data*            要添加的数据*/public void add(Object data) {// 判断该数据是否存在if (contains(data))return;// 1.把数据放到节点中Node node = new Node(data);// 2.把节点链接到二叉树中// 是否有根节点if (root == null) {root = node;// 保存到根节点中} else {// 找位置,找父节点,比较父节点的值,小左边 大右边Node parrent = findParrent(data, root);// 设置新增节点的父节点node.parrent = parrent;// 比较if (compare(data, parrent.data)) {// 自己比父节点大parrent.right = node;} else {// 自己比父节点小parrent.left = node;}}}/*** @param data* @return 是否包含该数据*/public boolean contains(Object data) {return null != find(data);}private Node find(Object data) {Node temp = root;// 从根节点找while (temp != null) {// 判断数据if (temp.data.equals(data)&& temp.data.hashCode() == data.hashCode()) {// 找到数据break;} else if (compare(data, temp.data)) {// true data > temp// 从右边找temp = temp.right;} else {// false data < temp// 从坐标边找temp = temp.left;}}return temp;}public void remove(Object data) {// 1. 查找数据是否存在Node temp = find(data);// 2. 存在:找到数据节点if (temp != null) {// 存在// 3. 删除节点// 1. 根节点if (temp == root) {// 11 没有儿子if (temp.left == null && temp.right == null) {root = null;} else if (temp.right == null) {root = root.left;root.parrent = null;// 12 只有左儿子} else if (temp.left == null) {// 13 只有右儿子root = root.right;root.parrent = null;} else {// 14 两个儿子都有// 保留左儿子Node left = getLeft(temp);// left成为新的根节点root = left;left.parrent = null;}} else {// 2. 非根节点if (temp.left == null && temp.right == null) {// 21 没有儿子if (compare(temp.data, temp.parrent.data)) {//在父节点右边temp.parrent.right = null;} else {//在父节点左边temp.parrent.left = null;}} else if (temp.right == null) {// 22 只有左儿子if (compare(temp.data, temp.parrent.data)) {//在父节点右边temp.parrent.right = temp.left;temp.left.parrent = temp.parrent;} else {//在父节点左边temp.parrent.left = temp.left;temp.left.parrent = temp.parrent;}} else if (temp.left == null) {// 23 只有右儿子if (compare(temp.data, temp.parrent.data)) {//在父节点右边temp.parrent.right = temp.right;temp.right.parrent = temp.parrent;} else {//在父节点左边temp.parrent.left = temp.right;temp.right.parrent = temp.parrent;}} else {// 24 两个儿子都有Node left = getLeft(temp);//上面还有父节点(爷爷)if (compare(left.data, temp.parrent.data)) {//比爷爷节点大temp.parrent.right = left;left.parrent = temp.parrent;} else  {//比爷爷节点小temp.parrent.left = left;left.parrent = temp.parrent;}}}}}/*** @param node*            要删除的节点* @return 左儿子节点*/private Node getLeft(Node node) {// 保留左儿子Node left = node.left;// 处理右节点Node rightNewParrent = findParrent(node.right.data, left);rightNewParrent.right = node.right;// 把删除节点的右节点放到删除节点的左儿子最右边node.right.parrent = rightNewParrent;return left;}/*** @param o1*            第一个值* @param o2*            第二个值* @return 如果o1 大于 o2 返回true 否则false*/public boolean compare(Object o1, Object o2) {boolean res = false;// 判断o1 有没有实现比较器if (o1 instanceof Comparable) {Comparable c1 = (Comparable) o1;Comparable c2 = (Comparable) o2;if (c1.compareTo(c2) > 0) {res = true;} else {// 默认值就是false}} else {// 传递的对象没有比较器res = o1.toString().compareTo(o2.toString()) > 0 ? true : false;}return res;}// 递归打印public void print() {print(root);}public void print(Node node) {if (node == null) {return;} else {// 遍历 中序print(node.left);System.out.println(node.data + ",");print(node.right);}}}

从currentNode节点开始查找data的父节点

private Node findParrent(Object data, Node currentNode) {// 从根节点找Node temp = currentNode;Node parrent = currentNode;// 循环找while (temp != null) {parrent = temp;// 比较if (compare(data, temp.data)) {// data 大于 当前节点temp = temp.right;} else {// data 小于 当前节点temp = temp.left;}}return parrent;}

删除节点,该节点有左右孩子

可以把右孩子添加到左孩子的右边,或者把左孩子添加到右孩子的左边

//node 要删除的节点
private Node getLeft(Node node) {// 保留左儿子Node left = node.left;// 处理右节点Node rightNewParrent = findParrent(node.right.data, left);rightNewParrent.right = node.right;// 把删除节点的右节点放到删除节点的左儿子最右边node.right.parrent = rightNewParrent;return left;}

删除节点

public void remove(Object data) {// 1. 查找数据是否存在Node temp = find(data);// 2. 存在:找到数据节点if (temp != null) {// 存在// 3. 删除节点// 1. 根节点if (temp == root) {// 11 没有儿子if (temp.left == null && temp.right == null) {root = null;} else if (temp.right == null) {root = root.left;root.parrent = null;// 12 只有左儿子} else if (temp.left == null) {// 13 只有右儿子root = root.right;root.parrent = null;} else {// 14 两个儿子都有// 保留左儿子Node left = getLeft(temp);// left成为新的根节点root = left;left.parrent = null;}} else {// 2. 非根节点if (temp.left == null && temp.right == null) {// 21 没有儿子if (compare(temp.data, temp.parrent.data)) {//在父节点右边temp.parrent.right = null;} else {//在父节点左边temp.parrent.left = null;}} else if (temp.right == null) {// 22 只有左儿子if (compare(temp.data, temp.parrent.data)) {//在父节点右边temp.parrent.right = temp.left;temp.left.parrent = temp.parrent;} else {//在父节点左边temp.parrent.left = temp.left;temp.left.parrent = temp.parrent;}} else if (temp.left == null) {// 23 只有右儿子if (compare(temp.data, temp.parrent.data)) {//在父节点右边temp.parrent.right = temp.right;temp.right.parrent = temp.parrent;} else {//在父节点左边temp.parrent.left = temp.right;temp.right.parrent = temp.parrent;}} else {// 24 两个儿子都有Node left = getLeft(temp);//上面还有父节点(爷爷)if (compare(left.data, temp.parrent.data)) {//比爷爷节点大temp.parrent.right = left;left.parrent = temp.parrent;} else  {//比爷爷节点小temp.parrent.left = left;left.parrent = temp.parrent;}}}}}

删除的节点非根节点,且右孩子为空

else if (temp.right == null) {// 只有左儿子if (compare(temp.data, temp.parrent.data)) {//在父节点右边,下图中的23temp.parrent.right = temp.left;temp.left.parrent = temp.parrent;} else {//在父节点左边,下图中的50temp.parrent.left = temp.left;temp.left.parrent = temp.parrent;}
}

else {// 两个儿子都有Node left = getLeft(temp);//上面还有父节点(爷爷)if (compare(left.data, temp.parrent.data)) {//比爷爷节点大,下图中的89temp.parrent.right = left;left.parrent = temp.parrent;} else  {//比爷爷节点小,下图中的45temp.parrent.left = left;left.parrent = temp.parrent;}
}

Java数据结构和算法:二叉树相关推荐

  1. Java数据结构和算法-二叉树

    https://www.cnblogs.com/ysocean/p/8032642.html#_label2 转载于:https://www.cnblogs.com/lancexu/p/9558616 ...

  2. 二叉树 BinaryTree (先序、中序、后序遍历 节点查找、插入、删除 完整类) Java数据结构与算法

    二叉树 BinaryTree (先序.中序.后序遍历 节点查找.插入.删除 完整类) Java数据结构与算法 源代码: view plain /** * * @author sunnyykn */ i ...

  3. Java数据结构与算法——树(基本概念,很重要)

    声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 有网友私信我,期待我的下一篇数据结构.非常荣幸文章被认可,也非常感谢你们的监督. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督 ...

  4. Java数据结构和算法(一)——简介

    本系列博客我们将学习数据结构和算法,为什么要学习数据结构和算法,这里我举个简单的例子. 编程好比是一辆汽车,而数据结构和算法是汽车内部的变速箱.一个开车的人不懂变速箱的原理也是能开车的,同理一个不懂数 ...

  5. java数据结构与算法之顺序表与链表深入分析

    转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52953190 出自[zejian的博客] 关联文章: java数据结 ...

  6. java数据结构与算法之双链表设计与实现

    转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/53047590 出自[zejian的博客] 关联文章: java数据结 ...

  7. Java 数据结构和算法(十五):无权无向图

    Java数据结构和算法(十五)--无权无向图 前面我们介绍了树这种数据结构,树是由n(n>0)个有限节点通过连接它们的边组成一个具有层次关系的集合,把它叫做"树"是因为它看起 ...

  8. Java数据结构和算法(第二版)

    Java数据结构和算法(第二版) 下载地址 https://pan.baidu.com/s/112D5houIgu0eMs_i5o0Ujw 扫码下面二维码关注公众号回复 100066获取分享码 本书目 ...

  9. java数据结构与算法之(Queue)队列设计与实现

    [版权申明]转载请注明出处(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/53375004 出自[zejian的博客] ...

  10. 数据结构 - Java -韩顺平 图解Java数据结构和算法

    数据结构 Lesson 1 数据结构的知识总结 1. 几个经典的算法面试题 2. 线性结构与非线性结构 2.1 稀疏数组 sparsearray 2.2 队列 2.2.1 顺序队列: 2.2.2 环形 ...

最新文章

  1. 《.NET应用架构设计:原则、模式与实践》新书博客--试读-1.3 架构设计中的重要概念...
  2. CentOS7+MySQL/MariaDB+Galera+HAProxy+Keepalived构建高可用数据库集群
  3. C语言实验——拍皮球_JAVA
  4. Wcf 双工通信的应用
  5. tf.layers.Dense与 tf.layers.dense的区别
  6. C语言:5行代码解决 L1-045 宇宙无敌大招呼 (5分)
  7. 布线问题分支限界法java_大型布线:Java云应用程序缺少的技术
  8. php dingo和jwt,dingo配合laravel、JWT使用
  9. 无限流量手机怎样改服务器,无限流量手机服务器
  10. java面试-Java并发编程(六)——线程间的通信
  11. 线程java作用_java线程介绍(原创)
  12. 两直线夹角求解-Python编程实现
  13. 如何查看有关计算机系统类型,电脑系统类型在哪查看
  14. pandas 取某一列数据的几种形式比较
  15. Zabbix 5.0 监控教程(一)
  16. [源码学习][知了开发]WebMagic-总体流程源码分析
  17. [转] 肾有多好人就有多年轻
  18. Android 标题栏及导航栏设计与实现
  19. 计算机基础知识(基础入门小白专属)三
  20. 朴素贝叶斯、费舍尔分类方法

热门文章

  1. cygwin 在 windows 下的安装
  2. LDP传输地址配置——Vecloud
  3. echart参数设置——曲线图
  4. ZOJ 1610 Count the Colors 【线段树】
  5. ZooKeeper安装及配置(Windows系统下)
  6. Netty入门(七)使用SSL/TLS加密Netty程序
  7. HDU-1170的解题报告
  8. python学习笔记系列----(五)输入和输出
  9. mysql workbench建表时PK,NN,UQ,BIN,UN,ZF,AI
  10. Linux关闭防火墙、SELinux