Java数据结构——二叉树 增加、删除、查询
//二叉树系统
public class BinarySystem {
public static void main(String[] args) {
BinaryDomain root = null; //定义头结点
new BinaryAction().manage(root);
}
}
public class BinaryDomain {
private int value; //二叉树值
BinaryDomain left; //左结点
BinaryDomain right; //右结点
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public BinaryDomain() {
super();
// TODO Auto-generated constructor stub
}
public BinaryDomain(int value) {
super();
this.value = value;
}
}
public interface BinaryBean {
public void manage(BinaryDomain root); //二叉树管理
public BinaryDomain add(BinaryDomain root); //二叉树增加
public BinaryDomain delete(BinaryDomain root); //二叉树删除
public void query(BinaryDomain root); //二叉树查询
public void update(BinaryDomain root); //二叉树修改
}
import java.util.Scanner;
public class BinaryAction implements BinaryBean{
private Scanner input = new Scanner(System.in);
@Override
public void manage(BinaryDomain root) {
while (true) {
System.out.println("①增加 ②删除 ③查询 ④修改 ⑤返回");
int select = input.nextInt();
if (select == 1) {
root = add(root);
} else if (select == 2) {
root = delete(root);
} else if (select == 3) {
query(root);
} else if (select == 4) {
update(root);
} else {
break;
}
}
}
//增加
@Override
public BinaryDomain add(BinaryDomain root) {
System.out.println("请输入需要增加的值: ");
int value = input.nextInt();
if (value < 0) {
System.out.println("输入的值不合法");
} else {
BinaryDomain binary = new BinaryDomain(value); //将值存入对象
if (root == null) { //头为空
root = binary; //将值给头
System.out.println("二叉树的头结点增加成功");
} else {
BinaryDomain temp = root; //将头保护起来
while (temp != null) {
//小左大右
if (binary.getValue() > temp.getValue()) {
//要增加的值大于当前头的值
if (temp.right == null) {
temp.right = binary;
System.out.println("添加右子树值成功");
break;
} else {
temp = temp.right;
}
} else if (binary.getValue() < temp.getValue()){
//要增加的值小于当前头的值
if (temp.left == null) {
temp.left = binary;
System.out.println("添加左子树值成功");
break;
} else {
temp = temp.left;
}
} else {
//要增加的值等于当前头的值
System.out.println("要增加的数值已存在,增加数据失败");
break;
}
}
}
}
return root;
}
//删除
@Override
public BinaryDomain delete(BinaryDomain root) {
BinaryDomain temp = root; //保护头结点
BinaryDomain tempPre = null; //要删除的前一个结点
BinaryDomain del = null; //记录要删除的结点
System.out.println("请输入需要删除的值: ");
int value = input.nextInt();
while (temp != null) {
if (temp.getValue() == value) {
//当前结点值 == 要删除的值
del = temp; //记录要删除的结点
break;
} else if (temp.getValue() > value) {
//当前结点值 > 要删除的值 往左移至下一个
tempPre = temp; //记录要删除结点的前一个结点
temp = temp.left;
} else {
//当前结点值 < 要删除的值 往右移至下一个
tempPre = temp;
temp = temp.right;
}
}
//判断要删除的结点是否为头结点
if (del != null && tempPre == null) {
System.out.println("要删除的为头结点");
if (del.left == null && del.right == null) {
//头结点 无左无右
root = null;
System.out.println("删除 无左无右 头结点成功");
} else if (del.left != null && del.right == null) {
//要删除的头结点 有左无右
root = del.left;
System.out.println("删除 有左无右 头结点成功");
} else if (del.left == null && del.right != null) {
//要删除的头结点 无左有右
root = del.right;
System.out.println("删除 无左有右 头结点成功");
} else {
//要删除的头结点 有左有右
System.out.println("要删除的头结点有左有右: ①上移左边的最右边结点值 ②上移右边的最左边结点值");
int option = input.nextInt();
if (option == 1) {
//移左边的最右边结点的值
BinaryDomain delLeft = del.left; //用一个对象指向要删除结点的左边
if (delLeft.right == null && delLeft.left == null) {
//如果要删除的结点的左边结点没有子结点,则把要删除的结点值等于delLeft值,需要删除结点的左结点为空
del.setValue(delLeft.getValue());
del.left = null;
System.out.println("删除 有左有右 头结点成功,头结点的左子树下 无子树");
} else if (delLeft.right == null && delLeft.left != null) {
//要删除的结点的左边结点 有左子树无右子树
del.setValue(delLeft.getValue());
del.left = delLeft.left;
System.out.println("删除 有左有右 头结点成功,头结点的左子树下 有左子树无右子树");
} else {
//要删除的结点的左边结点有右子树
BinaryDomain movePre = null; //记录删除结点左边结点的需要移走的最右边的结点的父结点
while (delLeft.right != null) {
movePre = delLeft;
delLeft = delLeft.right;
}
del.setValue(delLeft.getValue());
movePre.right = delLeft.left;
System.out.println("删除 有左有右 头结点成功,头结点的左子树下 有右子树 需要移动");
}
} else {
//移右边的最左边结点值
BinaryDomain delRight = del.right; //用一个对象指向要删除结点的右边
if (delRight.right == null && delRight.left == null) {
//如果要删除的结点的右边结点没有子结点,则把要删除的结点值等于delRight值,需要删除结点的右结点为空
del.setValue(delRight.getValue());
del.right = null;
System.out.println("删除 有左有右 头结点成功,头结点的右子树下 无子树");
} else if (delRight.right != null && delRight.left == null) {
//要删除的结点的右边结点 有右子树无左子树
del.setValue(delRight.getValue());
del.right = delRight.right;
System.out.println("删除 有左有右 头结点成功,头结点的右子树下 有右子树无左子树");
} else {
//要删除的结点的右边结点有左子树
BinaryDomain movePre = null; //记录删除结点右边结点的需要移走的最左边的结点的父结点
while (delRight.left != null) {
movePre = delRight;
delRight = delRight.left;
System.out.println("删除 有左有右 头结点成功,头结点的右子树下 有左子树 需要移动");
}
}
}
}
} else {
//要删除的不是头结点
if (del.left == null && del.right == null) {
//要删除的结点无左无右 为叶子结点
System.out.println("需要删除的为叶子结点");
if (del.getValue() > tempPre.getValue()) {
//要删除的值大于父结点的值 删除的为右叶子结点
tempPre.right = null;
System.out.println("删除非根结点下的右叶子结点成功");
} else {
//要删除的值小于父结点的值 删除的为左叶子结点
temp.left = null;
System.out.println("删除非根结点下的左叶子结点成功");
}
} else if (del.left == null && del.right != null) {
//要删除的结点无左有右
if (del.getValue() > tempPre.getValue()) {
//要删除的值大于父结点的值 要删除的为父结点下的右子树
tempPre.right = del.right;
System.out.println("删除非根结点下的右子树成功,且该右子树下 有右子树无左子树");
} else {
//要删除的值小于父结点的值 要删除的为父结点下的左子树
tempPre.left = del.right;
System.out.println("删除非根结点下的左子树成功,且该左子树下 有右子树无左子树");
}
} else if (del.left != null && del.right == null) {
//要删除的结点有左无右
if (del.getValue() > tempPre.getValue()) {
//要删除的值大于父结点的值 要删除的为父结点下的右子树
tempPre.right = del.left;
System.out.println("删除非根结点下的右子树成功,且该右子树下 有左子树无右子树");
} else {
//要删除的值小于父结点的值 要删除的为父结点下的左子树
tempPre.left = del.left;
System.out.println("删除非根结点下的左子树成功,且该左子树下 有左子树无右子树");
}
}else {
//要删除的结点有左有右
System.out.println("要删除的结点有左有右: ①上移左边的最右边结点值 ②上移右边的最左边结点值");
int option = input.nextInt();
if (option == 1) {
//移左边的最右边结点
BinaryDomain delLeft = del.left; //定义对象指向要删除结点的左边结点
if (delLeft.right == null && delLeft.left == null) {
//要删除结点的左边结点 无左子树无右子树
del.setValue(delLeft.getValue());
del.left = null;
System.out.println("删除非根结点下左子树成功,且该左子树下 无左子树无右子树");
} else if (delLeft.right == null && delLeft.left != null) {
//要删除结点的左边结点 有左子树无右子树
del.setValue(delLeft.getValue());
del.left = delLeft.left;
System.out.println("删除非根结点下左子树成功,且该左子树下 有左子树无右子树");
} else {
//要删除结点的左边结点 无左子树有右子树
BinaryDomain movePre = null; //记录删除结点左边结点的需要移走的最右边的结点的父结点
while (delLeft.right != null) {
movePre = delLeft;
delLeft = delLeft.right;
}
del.setValue(delLeft.getValue());
movePre.right = delLeft.left;
System.out.println("删除非根结点下左子树成功,且该左子树下 有右子树 需要移动");
}
} else {
//移右边的最左边结点
BinaryDomain delRight = del.right; //定义对象指向要删除结点的右结点
if (delRight.right == null && delRight.left == null) {
//要删除结点的右子树下无子树
del.setValue(delRight.getValue());
del.right = null;
System.out.println("删除非根结点下右子树成功,且该右子树下 无子树");
} else if (delRight.right != null && delRight.left == null) {
//要删除结点的右子树下有右子树无左子树
del.setValue(delRight.getValue());
del.right = delRight.right;
System.out.println("删除非根结点下右子树成功,且该右子树下 无左子树有右子树");
} else {
//要删除结点的右子树下有左子树
BinaryDomain movePre = null; //记录删除结点右边结点的需要移走的最左边的结点的父结点
while (delRight.left != null) {
movePre = delRight;
delRight = delRight.left;
}
del.setValue(delRight.getValue());
movePre.left = del.right;
System.out.println("删除非根结点下右子树成功,且该右子树下 有左子树 需要移动");
}
}
}
}
return root;
}
//查询
@Override
public void query(BinaryDomain root) {
System.out.println("①先序查询 ②中序查询 ③后序查询");
int select = input.nextInt();
if (select == 1) {
//先序查询 根 左 右
preorder(root);
} else if (select == 2) {
//中序查询 左 根 右
inorder(root);
} else {
//后序查询 左 右 根
epilogue(root);
}
}
//先序查询 根 左 右
public void preorder(BinaryDomain root) {
BinaryDomain temp = root;
if (temp != null) {
System.out.println("先序查询为: "+temp.getValue()); //根
preorder(temp.left); //左
preorder(temp.right); //右
}
}
//中序查询 左 根 右
public void inorder (BinaryDomain root) {
BinaryDomain temp = root;
if (temp != null) {
inorder(temp.left); //左
System.out.println("中序查询为: "+temp.getValue()); //根
inorder(temp.right); //右
}
}
//后序查询 左 右 根
public void epilogue (BinaryDomain root) {
BinaryDomain temp = root;
if (temp != null) {
epilogue (temp.left); //左
epilogue (temp.right); //右
System.out.println("后序查询为: "+temp.getValue()); //根
}
}
//修改
@Override
public void update(BinaryDomain root) {
System.out.println("请输入需要修改的数据元素: ");
int update = input.nextInt();
}
}
修改没写了 ,很麻烦 ,如有需要留言,告诉你具体实现思路。。
Java数据结构——二叉树 增加、删除、查询的更多相关文章
- (2)Java数据结构--二叉树 -和排序算法实现
=== 注释:此人博客对很多个数据结构类都有讲解-并加以实例 Java API —— ArrayList类 & Vector类 & LinkList类Java API —— BigDe ...
- java数据结构——二叉树(BinaryTree)
前面我们已经学习了一些线性结构的数据结构和算法,接下来我们开始学习非线性结构的内容. 二叉树 前面显示增.删.查.遍历方法,完整代码在最后面. /** * 为什么我们要学习树结构. * 1.有序数组插 ...
- Java数据结构——二叉树
前序遍历——根 左 右 中序遍历——左 根 右 后序遍历——左 右 根 //================================================= // File Name ...
- 树——平衡二叉树插入和查找的JAVA实现(2):增加删除方法
package com.tomsnail.data.tree; /** * AVL二叉平衡树 * @author tomsnail * @date 2015年3月30日 下午4:35:50 */ pu ...
- iptables中增加/删除/查询/修改的基本操作
虽然在Ubuntu使用了UFW来简化iptables的操作,但是UFW只针对防火墙方面,转发方面没有涉及,所以要弄懂其中的原理,还是必须回归到iptables中.CentOS也是如此.下面是针对ipt ...
- Java数据结构——二叉树的遍历(汇总)
二叉树的遍历分为深度优先遍历(DFS)和广度优先遍历(BFS) DFS遍历主要有: 前序遍历 中序遍历 后序遍历 一.递归实现DFSNode.java: public class Node { pri ...
- Java数据结构——二叉树节点的增删改查、获取深度及最大最小值
一.查找最大值 // 查找最大值 public static Node maxNode() { Node node = root; Node maxNode = node; while (node ! ...
- java数据结构(二叉树)
Node节点: public class Node { public long data; public String sData; public Node leftChild; public Nod ...
- Java数据结构和算法(四)赫夫曼树
Java数据结构和算法(四)赫夫曼树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 赫夫曼树又称为最优二叉树,赫夫曼树的一个 ...
随机推荐
- JavaScript的作用域(Scope)和上下文(Context)
JavaScript对于作用域(Scope)和上下文(Context)的实现是这门语言的一个非常独到的地方,部分归功于其独特的灵活性. 函数可以接收不同的的上下文和作用域.这些概念为JavaScrip ...
- Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性)
Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性) 前言:由于前段时间忙于写接口,在接口中需要做很多的参数校验,本着简洁.高效的原则,便写了这个小工具供自己使用(内容 ...
- SQLAlchemy的使用---M2M多对多关系
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, Stri ...
- css 简单梯形
通过css2D变形我们可以轻松得到平行四边形,那么通过此技巧可以得到梯形吗? no! 不过我们可以通过3D旋转得到类似这样的效果: transform:perspective(0.5em) rota ...
- ie 9 渐变背景色兼容问题
/*窗口背景*/ .window { background-color: #fff; background: -webkit-linear-gradient(top,#EFF5FF 0, ...
- ppt写作的注意事项
PPT推荐字体及大小: 宋体严谨,适合正文,显示最清晰 黑体庄重,适合标题,或者强调区 隶书楷体,艺术性强,不适合投影 如果通过文字排版突出重点:加粗.加大字号.变色 PPT文字太多怎么办? 1.抽象 ...
- Dubbo架构原理
1 Dubbo核心功能 Remoting:远程通讯,提供对多种NIO框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式. Cluster: 服务框架,提供基于接口方法的透明远程过程调用 ...
- 【Linux】Windows与Linux之间的文件共享(基于网络)
切记:Linux的安全机制的存在--iptables和selinux. 一.操作前提 1.1 从Windows能够ping通Linux 1.2 关闭Linux防火墙 command1:/etc/ini ...
- RBG灯颜色渐变(颜色要尽可能多)程序分析
相信很多调过RBG灯的朋友都是通过分别改变R.B.G的占空比来改变颜色的,但是不是发现了一个问题,那就是不管怎样调都很难实现几十种颜色的变化,一般只有是7种颜色的渐变.下面给朋友们分享一个可以实现几十 ...
- SOL的补充
之前写过一些关于远程安装系统的文档,但是对于SOL还是糊涂不清. Serial Console 可以将输入输出转发到串行接口(com1, com2), 假如你有串行读取设备,就可以看到显示,控制输入. ...