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));
    }

}

好了,就是这样!

时间: 2024-10-25 17:53:46

Java创建二叉搜索树,实现搜索,插入,删除操作的相关文章

二叉搜索树非递归方式删除节点

#include "stdio.h" #include "iostream.h" typedef struct node { int data ; node*lChild ; node*rChild ; }TreeNode ; void Insert(TreeNode**root,int data) //向二叉查找树中插入元素 采用非递归思想 { TreeNode * p=*root ;//获得根结点 TreeNode*q=new TreeNode ;//分配一个要

二叉搜索树与双向链表的C++实现

题目:输入一颗二叉搜索树, 将该二叉搜索树转换成一个排序的双向链表. 要求不能创建任何新的结点, 只能调整数中结点的指针的指向. 方法: 使用中序遍历每一个结点, 并进行连接, 即左子树指前, 右子树指后, 并保存前一个节点. 本程序包含算法原理, 测试程序, 及 输出. 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <iostream> #i

二叉搜索树的非递归创建和搜索

#include "stdio.h" typedef struct node { int data ; node*lChild ; node*rChild ; }TreeNode ; void Insert(TreeNode**root,int data) //向二叉查找树中插入元素 采用非递归思想 { TreeNode * p=*root ;//获得根结点 TreeNode*q=new TreeNode ;//分配一个要插入的新节点 q->lChild=q->rChild

二叉搜索树的插入与删除(详细解析)_C 语言

题目:创建一个类,类中的数据成员时一棵二叉搜索树,对外提供的接口有添加结点和删除结点这两种方法.用户不关注二叉树的情况.要求我们给出这个类的结构以及实现类中的方法. 思路添加结点:添加结点其实很容易,我们只需要找到结点所行对应的位置就可以了,而且没有要求是平衡的二叉搜索树,因此每次添加结点都是在叶子结点上操作,不需要修改二叉搜索树整体的结构.要找出添加节点在二叉搜索树中的位置,可以用一个循环解决.判断插入结点与当前头结点的大小,如果大于头结点则继续搜索右子树,如果小于头结点则继续搜索左子树.直到

Java实现 二叉搜索树算法(BST)

一.树 & 二叉树 树是由节点和边构成,储存元素的集合.节点分根节点.父节点和子节点的概念. 如图:树深=4; 5是根节点:同样8与3的关系是父子节点关系. 二叉树binary tree,则加了"二叉"(binary),意思是在树中作区分.每个节点至多有两个子(child),left child & right child.二叉树在很多例子中使用,比如二叉树表示算术表达式. 如图:1/8是左节点:2/3是右节点: 二.二叉搜索树 BST 顾名思义,二叉树上又加了个搜索的

【算法学习】AVL平衡二叉搜索树原理及各项操作编程实现(C++)

AVLTree即(Adelson-Velskii-Landis Tree),是加了额外条件的二叉搜索树.其平衡条件的建立是为了确保整棵树的深度为O(nLogn).平衡条件是任何节点的左右子树的高度相差不超过1.   在下面的代码中,编程实现了AVL树的建立.查找.插入.删除.遍历等操作.采用C++类封装. AVL树中比较复杂的操作时插入和删除操作.在这里对插入和删除操作进行讲解.   AVL树的插入操作 向AVL树中插入元素可能会导致树失去平衡.但是,我们只需要调整插入点至根节点的路径上不满足平

[华为机试练习题]33.二叉搜索树

题目 描述: 判断两序列是否为同一二叉搜索树序列 题目类别: 树 难度: 中级 运行时间限制: 10Sec 内存限制: 128MByte 阶段: 入职前练习 输入: 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树. 接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树. 输出: 如果序列相同则输出YES

纸上谈兵: 树, 二叉树, 二叉搜索树[转]

树的特征和定义 树(Tree)是元素的集合.我们先以比较直观的方式介绍树.下面的数据结构是一个树: 树有多个节点(node),用以储存元素.某些节点之间存在一定的关系,用连线表示,连线称为边(edge).边的上端节点称为父节点,下端称为子节点.树像是一个不断分叉的树根. 每个节点可以有多个子节点(children),而该节点是相应子节点的父节点(parent).比如说,3,5是6的子节点,6是3,5的父节点:1,8,7是3的子节点, 3是1,8,7的父节点.树有一个没有父节点的节点,称为根节点(

二叉搜索树(Binary Search Tree)--C语言描述(转)

图解二叉搜索树概念 二叉树呢,其实就是链表的一个二维形式,而二叉搜索树,就是一种特殊的二叉树,这种二叉树有个特点:对任意节点而言,左孩子(当然了,存在的话)的值总是小于本身,而右孩子(存在的话)的值总是大于本身. 下面来介绍在此种二叉树结构上的查找,插入,删除算法思路. 查找:因为这种结构就是为了来方便查找的,所以查找其中的某个值很容易,从根开始,小的往左找,大的往右找,不大不小的就是这个节点了: 代码很简单,这里就不写了. 插入:插入一样的道理,从根开始,小的往左,大的往右,直到叶子,就插入.