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创建二叉搜索树,实现搜索,插入,删除操作的更多相关文章

  1. 二叉搜索树-php实现 插入删除查找等操作

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的 ...

  2. Java实现二叉搜索树

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11406176.html 尝试一下用Java实现二叉搜索树/二叉查找树,记录自己的学习历程. 1 ...

  3. 二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历

    二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历   二叉搜索树的结构(30 分) 二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则 ...

  4. Java实现二叉搜索树的插入、删除

    前置知识 二叉树的结构 public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() { } TreeNode( ...

  5. Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作

    什么也不说了,直接上代码. 首先是节点类,大家都懂得 /** * 二叉树的节点类 * * @author HeYufan * * @param <T> */ class Node<T ...

  6. 二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历

    二叉搜索树的结构(30 分) 二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值:若它的右子树不空,则右子树上所有结点的值均大于它的根 ...

  7. Java实现二叉搜索树及相关操作

    package com.tree; import com.tree.BitNode; /** * * 二叉搜索树:一个节点的左子节点的关键字小于这个节点.右子节点的关键字大于或等于这个父节点 * * ...

  8. Java数据结构——二叉搜索树

    定义二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若 ...

  9. Java对二叉搜索树进行插入、查找、遍历、最大值和最小值的操作

    1.首先,须要一个节点对象的类.这些对象包括数据.数据代表存储的内容,并且还有指向节点的两个子节点的引用 class Node { public int iData; public double dD ...

随机推荐

  1. bootmgr is missing 开机无法进系统怎么办

    认识 bootmgr: 启动管理器.Bootmgr是Boot Manager的缩写,是在Windows Vista和Windows 7中使用的新的启动管理器,以代替Windows xp中的启动管理器- ...

  2. eclipse的maven操作无反应

    第一 查eclipse能不能正常用 hi world.java 第二 查maven能不能正常用 cmd: mvn -v 第三 看看maven和eclipse是不是64位之类的 第四 maven和ecl ...

  3. Jackson工具

    Jackson Jackson包含一个core JAR,和两个依赖core JAR的JAR: jackson-core-2.2.3.jar(核心jar包,下载地址) jackson-annotatio ...

  4. 利用Express模拟web安全之---xss的攻与防

    一.什么是XSS? 跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS.恶意 ...

  5. HTMLParser使用简介

    HTMLParser具有小巧,快速的优点,缺点是相关文档比较少(英文的也少),很多功能需要自己摸索.对于初学者还是要费一些功夫的,而一旦上手以后,会发现HTMLParser的结构设计很巧妙,非常实用, ...

  6. Unity使用C++作为游戏逻辑脚本的研究

    文章申明:本文来自JacksonDunstan的博客系列文章内容摘取和翻译,版权归其所有,附上原文的链接,大家可以有空阅读原文:C++ Scripting( in Unity) 一.C#和C++的通信 ...

  7. Laravel-admin 七牛云上传文件到七牛云出现卡顿失败情况

    由于所做项目需要管理后台众多,所以选择了Laravel-admin后台框架进行开发.节省了权限控制以及页面处理等问题的时间 Laravel-admin文档地址 http://laravel-admin ...

  8. Python中如何将二维列表转换成一维列表

    已知:a = [(4,2,3), (5, 9, 1), (7,8,9)]希望将二维列表转换成一维列表:["4,2,3", "5, 9, 1", "7, ...

  9. 中间件——canal小记

    接到个小需求,将mysql的部分数据增量同步到es,但是不仅仅是使用canal而已,整体的流程是mysql>>canal>>flume>>kafka>> ...

  10. MongoDB 删除文档

    ongoDB remove()函数是用来移除集合中的数据. MongoDB数据更新可以使用update()函数.在执行remove()函数前先执行find()命令来判断执行的条件是否正确,这是一个比较 ...