数据结构——二叉树 增加、删除、查询

2023-11-12

 
//二叉树系统
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();
	}
}
修改有点麻烦,如需要请留言 告诉你思路~~~



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构——二叉树 增加、删除、查询 的相关文章

随机推荐

  • 使用HAL库开发STM32:UART基础使用

    文章目录 目的 基础说明与初始化 基础说明 初始化 数据接收和发送 轮询方式 中断方式 DMA方式 其它说明 总结 目的 UART 异步串口 是单片机非常常用的一个功能 一般用作设备或模块间通讯的一种方式 通常所说的232或是485通讯从写
  • JavaScript基础--内置对象之Math对象

    Math 对象不是构造函数 不需要new 它具有数学常数和函数的属性和方法 跟数学相关的运算 求绝对值 取整 最大值等 可以使用 Math 中的成员 1 Math对象常用方法 1 1 Max floor Max floor floor表示地
  • sql的基本操作详解

    一 什么是视图 视图 view 是一种虚拟存在的表 是一个逻辑表 本身并不包含数据 作为一个select语句保存在数据字典中的 二 为什么要用视图 视图隐藏了底层的表结构 简化了数据访问操作 客户端不再需要底层表的机构及其之间的关系 视图是
  • UE4 C++获取StaticMesh详细信息

    h UFUNCTION BlueprintCallable Category FunTool void GetStaticMeshDetails UStaticMesh Staticmesh TMap
  • 做期货的时候想到自己挣的钱都是别人亏的钱吗?

    1 换股法 当觉得自己的理财产品实在是没有什么时机了 就选一只与该理财产品价格差不多的 有时机上涨的理财产品来换 也便是等价 或根本等价 换入有上涨期望的理财产品 让后边买入的理财产品上涨后的赢利来抵消前面买入的理财产品因跌落而发生的亏本
  • Spring事务配置文件方式

  • BOOST 库中filesyatem 库的学习

    FileSyatem 库的学习 库的使用方式 嵌入源码的形式 define BOOST SYSTEN NO LIB define BOOST FILESYSTEM NO LIB include
  • 配置文件(properties类)

    基本介绍 1 专门用于读写配置文件的集合类 配置文件格式 键 值 2 注意 键值对 不需要空格 值 不需要用引号 默认类型 String 3 Properties的常见方法 1 load 加载配置文件的键值对到Properties对象 2
  • Win11怎么设置电脑开机密码和锁屏密码

    相信很多用户都已经用上了微软公司为大家提供的全新Win11系统了 Win11与Win10系统有很大区别 不仅仅体现在界面设计和UI上面 狠多以前Win10用户固定的功能有些取消了 有些挪位置了 这让用惯了Win10系统的用户非常不习惯 下面
  • Lua和C++交互详细总结

    转自 http cn cocos2d x org tutorial show id 1474 一 Lua堆栈 要理解Lua和C 交互 首先要理解Lua堆栈 简单来说 Lua和C C 语言通信的主要方法是一个无处不在的虚拟栈 栈的特点是先进后
  • Scrum猪和鸡的故事

    本文转载至 http blog csdn net fen0707 article details 8979942 一天 一头猪和一只鸡在路上散步 鸡看了一下猪说 嗨 我们合伙开一家餐馆怎么样 猪回头看了一下鸡说 好主意 那你准备给餐馆卖什么
  • Java Error org.apache.thrift.transport.TTransportException

    org apache thrift transport TTransportException java net ConnectException Connection refused connect org apache thrift t
  • 利用Python绘制中国新型冠状病毒疫情图(国家和省)

    大数据课程设计上来就要求绘制一个地图可以反应出来中国各个省份每日疫情的人数 包括确诊 疑似 死亡 治愈 如下图所示 这里用到了Python中的pyecharts库 点此了解详细信息 1 先来将需要的模块导入进来 import request
  • Windows 系统上如何安装 Python 环境(详细教程)

    一 下载 64位下载链接 https www python org ftp python 3 7 9 python 3 7 9 amd64 exe 32位下载链接 https www python org ftp python 3 7 9
  • QCheckBox复选框状态设置、信号绑定

    一 QCheckBox有两种设置状态 1 setCheckState Qt Checked 设置状态并且发送信号出去 eg for auto itr m mCheckBoxNum begin itr m mCheckBox end itr
  • (Java)leetcode-814 Binary Tree Pruning(二叉树剪枝)

    题目描述 给定二叉树根结点 root 此外树的每个结点的值要么是 0 要么是 1 返回移除了所有不包含 1 的子树的原二叉树 节点 X 的子树为 X 本身 以及所有 X 的后代 示例1 输入 1 null 0 0 1 输出 1 null 0
  • JDBC工作原理

    JDBC程序描述为包含如下过程的应用 1 引入一个必要的类2 加载JDBC驱动程序3 标识数据源 URL Username Password 4 分配一个Connection对象5 分配一个Statement对象6 使用该Statement
  • 阿里云部署Stable Diffusion

    系列文章目录 本地部署Stable Diffusion教程 亲测可以安装成功 Stable Diffusion界面参数及模型使用 谷歌Colab云端部署Stable Diffusion 进行绘图 文章目录 系列文章目录 前言 一 AIGC是
  • 外挂原理

    一 前言 所谓游戏外挂 其实是一种游戏外辅程序 它可以协助玩家自动产生游戏动作 修 改游戏网络数据包以及修改游 戏内存数据等 以实现玩家用最少的时间和金钱去完成功力升级和过关斩将 虽然 现 在对游戏外挂程序的 合法 身份众说纷纭 在这里我不
  • 数据结构——二叉树 增加、删除、查询

    二叉树系统 public class BinarySystem public static void main String args BinaryDomain root null 定义头结点 new BinaryAction manage