Java数据结构和算法:二叉树
二叉树的实现
数组查询快,增删慢;链表增删快,查询慢;二叉树查询和增删都有很好的性能
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数据结构和算法:二叉树相关推荐
- Java数据结构和算法-二叉树
https://www.cnblogs.com/ysocean/p/8032642.html#_label2 转载于:https://www.cnblogs.com/lancexu/p/9558616 ...
- 二叉树 BinaryTree (先序、中序、后序遍历 节点查找、插入、删除 完整类) Java数据结构与算法
二叉树 BinaryTree (先序.中序.后序遍历 节点查找.插入.删除 完整类) Java数据结构与算法 源代码: view plain /** * * @author sunnyykn */ i ...
- Java数据结构与算法——树(基本概念,很重要)
声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 有网友私信我,期待我的下一篇数据结构.非常荣幸文章被认可,也非常感谢你们的监督. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督 ...
- Java数据结构和算法(一)——简介
本系列博客我们将学习数据结构和算法,为什么要学习数据结构和算法,这里我举个简单的例子. 编程好比是一辆汽车,而数据结构和算法是汽车内部的变速箱.一个开车的人不懂变速箱的原理也是能开车的,同理一个不懂数 ...
- java数据结构与算法之顺序表与链表深入分析
转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52953190 出自[zejian的博客] 关联文章: java数据结 ...
- java数据结构与算法之双链表设计与实现
转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/53047590 出自[zejian的博客] 关联文章: java数据结 ...
- Java 数据结构和算法(十五):无权无向图
Java数据结构和算法(十五)--无权无向图 前面我们介绍了树这种数据结构,树是由n(n>0)个有限节点通过连接它们的边组成一个具有层次关系的集合,把它叫做"树"是因为它看起 ...
- Java数据结构和算法(第二版)
Java数据结构和算法(第二版) 下载地址 https://pan.baidu.com/s/112D5houIgu0eMs_i5o0Ujw 扫码下面二维码关注公众号回复 100066获取分享码 本书目 ...
- java数据结构与算法之(Queue)队列设计与实现
[版权申明]转载请注明出处(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/53375004 出自[zejian的博客] ...
- 数据结构 - Java -韩顺平 图解Java数据结构和算法
数据结构 Lesson 1 数据结构的知识总结 1. 几个经典的算法面试题 2. 线性结构与非线性结构 2.1 稀疏数组 sparsearray 2.2 队列 2.2.1 顺序队列: 2.2.2 环形 ...
最新文章
- 《.NET应用架构设计:原则、模式与实践》新书博客--试读-1.3 架构设计中的重要概念...
- CentOS7+MySQL/MariaDB+Galera+HAProxy+Keepalived构建高可用数据库集群
- C语言实验——拍皮球_JAVA
- Wcf 双工通信的应用
- tf.layers.Dense与 tf.layers.dense的区别
- C语言:5行代码解决 L1-045 宇宙无敌大招呼 (5分)
- 布线问题分支限界法java_大型布线:Java云应用程序缺少的技术
- php dingo和jwt,dingo配合laravel、JWT使用
- 无限流量手机怎样改服务器,无限流量手机服务器
- java面试-Java并发编程(六)——线程间的通信
- 线程java作用_java线程介绍(原创)
- 两直线夹角求解-Python编程实现
- 如何查看有关计算机系统类型,电脑系统类型在哪查看
- pandas 取某一列数据的几种形式比较
- Zabbix 5.0 监控教程(一)
- [源码学习][知了开发]WebMagic-总体流程源码分析
- [转] 肾有多好人就有多年轻
- Android 标题栏及导航栏设计与实现
- 计算机基础知识(基础入门小白专属)三
- 朴素贝叶斯、费舍尔分类方法