Java创建二叉搜索树,实现搜索,插入,删除操作
Java实现的二叉搜索树,并实现对该树的搜索,插入,删除操作(合并删除,复制删除)
首先我们要有一个编码的思路,大致如下:
1、查找:根据二叉搜索树的数据特点,我们可以根据节点的值得比较来实现查找,查找值大于当前节点时向右走,反之向左走!
2、插入:我们应该知道,插入的全部都是叶子节点,所以我们就需要找到要进行插入的叶子节点的位置,插入的思路与查找的思路一致。
3、删除:
1)合并删除:一般来说会遇到以下几种情况,被删节点有左子树没右子树,此时要让当前节点的父节点指向当前节点的左子树;当被删节点有右子树没有左子树,此时要让当前节点的父节点指向该右子树;当被删节点即有左子树又有右子树时,我们可以找到被删节点的左子树的最右端的节点,然后让这个节点的右或者左“指针”指向被删节点的右子树
2)复制删除:复制删除相对而言是比较简单的删除操作,也是最为常用的删除操作。大致也有以下三种情况:当前节点无左子树有右子树时,让当前右子树的根节点替换被删节点;当前节点无右子树有左子树时,让当前左子树的根节点替换被删除节点;当前被删节点既有左子树又有右子树时,我们就要找到被删节点的替身,可以在被删节点的左子树中找到其最右端的节点,并让这个节点的值赋给被删节点,然后别忘了让此替身节点的父节点指向替身的“指针”为空,(其实在Java中无关紧要了,有垃圾处理机制自动进行处理)。你也可以在当前被删节点的右子树的最左端的节点作为替身节点来实现这一过程。
接下来就上代码吧。
首先是## 二叉搜索树节点类 ##
package SearchBinaryTree;
public class SearchBinaryTreeNode<T> {
T data;
public SearchBinaryTreeNode<T> leftChild;
public SearchBinaryTreeNode<T> rightChild;
public SearchBinaryTreeNode(){
this.data=null;
this.leftChild=this.rightChild=null;
}
public SearchBinaryTreeNode(T da){
this.data=da;
this.leftChild=this.rightChild=null;
}
public SearchBinaryTreeNode(T da,SearchBinaryTreeNode<T> left,SearchBinaryTreeNode<T>right){
this.data=da;
this.leftChild=left;
this.rightChild=right;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public SearchBinaryTreeNode<T> getLeftChild() {
return leftChild;
}
public void setLeftChild(SearchBinaryTreeNode<T> leftChild) {
this.leftChild = leftChild;
}
public SearchBinaryTreeNode<T> getRightChild() {
return rightChild;
}
public void setRightChild(SearchBinaryTreeNode<T> rightChild) {
this.rightChild = rightChild;
}
public boolean isLeaf(){
if(this.leftChild==null&&this.rightChild==null){
return true;
}
return false;
}
}
实现二叉搜索树
package SearchBinaryTree;
public class SearchBinaryTree<T> {
SearchBinaryTreeNode<T> root;
public boolean isEmpty(){
if(root==null){
return true;
}
return false;
}
public void Visit(SearchBinaryTreeNode<T> root){
if(root==null){
System.out.println("this tree is empty!");
}
System.out.println(root.getData());
}
public SearchBinaryTreeNode<T> getRoot(){
if(root==null){
root=new SearchBinaryTreeNode<T>();
}
return root;
}
public SearchBinaryTree(){
this.root=null;
}
/*
* 创造一颗二叉树
*/
public void CreateTree(SearchBinaryTreeNode<T> node, T data) {
if (root == null) {
root = new SearchBinaryTreeNode<T>();
} else {
if (Math.random() > 0.5) { //采用随机方式创建二叉树
if (node.leftChild == null) {
node.leftChild = new SearchBinaryTreeNode<T>(data);
} else {
CreateTree(node.leftChild, data);
}
} else {
if (node.rightChild == null) {
node.rightChild = new SearchBinaryTreeNode<T>(data);
} else {
CreateTree(node.rightChild, data);
}
}
}
}
/*
* 在二查搜索树中进行搜索
*/
public SearchBinaryTreeNode<T> search(SearchBinaryTreeNode<T> root,T value){
SearchBinaryTreeNode<T> current=root;
while((root!=null)&&(current.getData()!=value)){
//需要注意的是java中泛型无法比较大小,在实际的使用时我们可以使用常见的数据类型来替代这个泛型,这样就不会出错了
current=(value<current.getData()?search(current.leftChild,value):search(current.rightChild,value));
}
return current;
}
public SearchBinaryTreeNode<T> insertNode( T value){
SearchBinaryTreeNode<T> p=root,pre=null;
while(p!=null){
pre=p;
//需要注意的是java中泛型无法比较大小,在实际的使用时我们可以使用常见的数据类型来替代这个泛型,这样就不会出错了
if(p.getData()<value){
p=p.rightChild;
}else{
p=p.leftChild;
}
}
if(root==null){
root=new SearchBinaryTreeNode<T>(value);
}else if(pre.getData()<value){
pre.rightChild=new SearchBinaryTreeNode<T>(value);
}else{
pre.leftChild=new SearchBinaryTreeNode<T>(value);
}
}
/*
* 合并删除
*/
public void deleteByMerging(SearchBinaryTreeNode<T> node){
SearchBinaryTreeNode<T> temp=node;
if(node!=null){
//若被删除节点没有右子树,用其左子树的根节点来代替被删除节点
if(node.rightChild!=null){
node=node.leftChild;
}else if(node.leftChild==null){
//若被删节点没有左子树,用其有字数的最左端的节点代替被删除的节点
node=node.rightChild;
}else{
//如果被删节点左右子树均存在
temp=node.leftChild;
while(temp.rightChild!=null){
temp=temp.rightChild; //一直查找到左子树的右节点
}
//将查找到的节点的右指针赋值为被删除节点的右子树的根
temp.rightChild=node.rightChild;
temp=node;
node=node.leftChild;
}
temp=null;
}
}
/*
* 复制删除
*/
public void deleteByCoping(SearchBinaryTreeNode<T> node){
SearchBinaryTreeNode<T> pre=null;
SearchBinaryTreeNode<T> temp=node;
//如果被删节点没有右子树,用其左子树的根节点来代替被删除节点
if(node.rightChild==null){
node=node.leftChild;
}else if(node.leftChild==null){
node=node.rightChild;
}else{
//如果被删节点的左右子树都存在
temp=node.leftChild;
pre=node;
while(temp.rightChild!=null){
pre=temp;
temp=temp.rightChild; //遍历查找到左子树的最右端的节点
}
node.data=temp.data; //进行赋值操作
if(pre==node){
pre.leftChild=node.leftChild;
}else{
pre.rightChild=node.rightChild;
}
}
temp=null;
}
}
测试类
package SearchBinaryTree;
public class SearchBinaryTreeTest {
public static void main(String []args){
SearchBinaryTree<Integer> tree=new SearchBinaryTree<Integer>();
for(int i=1;i<10;i++){
tree.CreateTree(new SearchBinaryTreeNode<Integer>(), i);
}
//搜索
tree.search(tree.root, 7);
//合并删除
tree.deleteByMerging(new SearchBinaryTreeNode<Integer>(8));
//复制删除
tree.deleteByCoping(new SearchBinaryTreeNode<Integer>(6));
}
}
好了,就是这样!
Java创建二叉搜索树,实现搜索,插入,删除操作的更多相关文章
- 二叉搜索树-php实现 插入删除查找等操作
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的 ...
- Java实现二叉搜索树
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11406176.html 尝试一下用Java实现二叉搜索树/二叉查找树,记录自己的学习历程. 1 ...
- 二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历
二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历 二叉搜索树的结构(30 分) 二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则 ...
- Java实现二叉搜索树的插入、删除
前置知识 二叉树的结构 public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() { } TreeNode( ...
- Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作
什么也不说了,直接上代码. 首先是节点类,大家都懂得 /** * 二叉树的节点类 * * @author HeYufan * * @param <T> */ class Node<T ...
- 二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历
二叉搜索树的结构(30 分) 二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值:若它的右子树不空,则右子树上所有结点的值均大于它的根 ...
- Java实现二叉搜索树及相关操作
package com.tree; import com.tree.BitNode; /** * * 二叉搜索树:一个节点的左子节点的关键字小于这个节点.右子节点的关键字大于或等于这个父节点 * * ...
- Java数据结构——二叉搜索树
定义二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若 ...
- Java对二叉搜索树进行插入、查找、遍历、最大值和最小值的操作
1.首先,须要一个节点对象的类.这些对象包括数据.数据代表存储的内容,并且还有指向节点的两个子节点的引用 class Node { public int iData; public double dD ...
随机推荐
- Linux下常用设置文件和文件夹读写权限操作
1.查看权限 ls -l xxx.xxx (xxx.xxx是文件名) 2.常见权限 -rw------- (600) 只有所有者才有读和写的权限 -rw-r--r-- (644) 只有所有者才有读 ...
- iOS Push详述,了解一下?
WeTest 导读 本文主要对iOS Push的在线push.本地push及离线(远程)push进行梳理,介绍了相关逻辑,测试时要注意的要点以及相关工具.小小的Push背后蕴藏着大大的逻辑! Push ...
- Django Views(视图函数)
http请求中产生两个核心对象: http请求:HttpRequest对象 http响应:HttpResponse对象 所在位置:django.http 之前我们用到的参数request就是HttpR ...
- C实战:项目构建Make,Automake,CMake
C实战:项目构建Make,Automake,CMake 在本系列文章<C实战:强大的程序调试工具GDB>中我们简要学习了流行的调试工具GDB的使用方法.本文继续"C实战" ...
- cassandra 3.x官方文档(3)---gossip通信协议及故障检测与恢复
写在前面 cassandra3.x官方文档的非官方翻译.翻译内容水平全依赖本人英文水平和对cassandra的理解.所以强烈建议阅读英文版cassandra 3.x 官方文档.此文档一半是翻译,一半是 ...
- Linux 性能监测:CPU
CPU 的占用主要取决于什么样的资源正在 CPU 上面运行,比如拷贝一个文件通常占用较少 CPU,因为大部分工作是由 DMA(Direct Memory Access)完成,只是在完成拷贝以后给一个中 ...
- activiti 多实例任务
1.1.1. 前言 个人,那么当5个人都投票的时候大概分为如下几种: 1.部门所有人都去投票,当所有人都投票完成的时候,这个节点结束,流程运转到下一个节点.(所有的人都需要投票) 2.部门所有人都去投 ...
- SceneKit:简单的3D游戏场景搭建
SceneKit是Apple用来开发休闲3D游戏的框架,不同于底层的OpenGL库,你仅仅需要很少的代码就可以快速看到实际的3D场景效果.下面简单的聊聊搭建一个3D游戏场景需要做的事情. 首先你必须用 ...
- 自制Linux 终端 锁屏防窃助手
很多时候我们不能一直守护在自己的电脑旁边,而且有些文件并不想让别人知道.那么这时候来个锁屏,是再合适不过的了.今天分享一个自制的锁屏工具,如下. 准备 操作系统 : 我这里是ElementaryOS虚 ...
- Java之继承深刻理解
1.关于私有成员变量 无论父类中的成员变量是私有的.共有的.还是其它类型的,子类都会拥有父类中的这些成员变量.但是父类中的私有成员变量,无法在子类中直接访问,必须通过从父类中继承得到的protecte ...