手写二叉搜索树(Java实现)

二叉搜索树的概念

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

这里写图片描述

二叉搜索树的代码实现

定义二叉搜索树的数据结构及基本方法

//定义树节点
public class Node{

        private int key;        //节点索引
        private int value;      //节点值
        private int count;      //节点个数
        private Node left;      //左孩子
        private Node right;     //右孩子
        //
        public Node(int key,int value){
            this.key = key;
            this.value = value;
            this.left = this.right = null;
        }
        //返回树的节点个数
        public int size(){
            return count;
        }
        //判断树空
        public boolean isEmpty(){
            return count == 0; 
        }

}

为二叉树插入一个节点

采用递归的方法向树中插入节点,比较节点索引值,若要插入的节点的索引小于当前节点索引,则插入到当前节点的”左边”,若要插入节点的索引大于当前节点索引,则插入到当前节点的右边,要插入节点索引与当前节点相等时替换当前节点的节点value,

//向根节点为root的树中插入节点
public Node insert(Node root , int key,int value){
    if(root == null){
        count++;
        return new Node(key,value);
    }
    if(key == root.key)
        root.value = value;
    if(key < root.key)
        root.left = insert(root.left,key,value);
    if(key > root.key)
        root.right = insert(root.right,key,value);
    //返回root
    return root;
}

查找索引为key的节点

        //二叉搜索树查找,按键查找
        public Node search(Node root,int key){
            if(root == null)
                return null;
            if(root.key == key)
                return root;
            else if(key < root.key)
                return search(root.left,key);
            else
                return search(root.right,key);
        }

删除树中索引最小的节点

索引最小的节点在树的最左下角,在删除时需要判断此要删除的节点是否还有右子树,若有需要将右子树替换到被删除的位置

        //删除最小值
        public Node deleteMin(Node root){
            //删除最小值前判断其是否有右子树
            if(root.left == null){
                Node node = root.right;
                count--;
                return node;
            }
            root.left = deleteMin(root.left);
            return root;
        }

删除树索引中最大的节点

        //删除最大值
        public Node deleteMax(Node root){
            //删除最大节点前判断其是否有左子树
            if(root.right == null){
                Node node = root.left;
                count--;
                return node;
            }
            root.right = deleteMax(root.right);
            return root;
        }

删除树中任意节点(相对复杂)

按照索引key找到需要删除的节点,此时要分情况讨论:
1、要删除的节点左子树为空:将此节点的右子树替换要删除节点的位置
2、要删除的节点右子树为空:将此节点的左子树替换要删除位置
3、左右子树都不为空:寻找此节点右子树的最小索引节点替换要删除节点位置,或者寻找左子树的最大索引节点替换要删除的节点

        //删除二叉搜索树中的任意节点
        public Node deleteNode(Node root,int key){
            if(root == null)
                return null;
            if(key < root.key){
                root.left = deleteNode(root.left,key);
                return root;
            }else if(key > root.key){
                root.right = deleteNode(root.right,key);
                return root;
            }else{
                //找到该节点,判断该节点有无左右子树
                if(root.left == null){
                    Node node = root.right;
                    count--;
                    return node;
                }
                if(root.right == null){
                    Node node = root.left;
                    count--;
                    return node;
                }
                //左右子树都不为空的情况下,寻找右子树中最小节点替代要删除 的节点
                //寻找要删除节点的右子树中索引最小的节点
                Node successor = findMin(root.right);
                //删除要删除节点的左子树中的最小索引节点
                successor.right = deleteMin(root.right);
                successor.left = root.left;
                return successor;
            }
        }

        public Node findMin(Node root){
            if(root.left != null)
                return findMin(root.left);
            return root;
        }

二叉树的先序、中序、后序遍历

二叉树的先序中序后序遍历只需要分别在先序中序后序位置输出节点信息就行了

        //先序遍历
        public void preOrder(Node root){
            if(root != null){
                //先序位置输出节点信息
                System.out.print(root.key+"->");
                preOrder(root.left);
                preOrder(root.right);
            }
        }

        //中序遍历
        public void inOrder(Node root){
            if(root != null){
                inOrder(root.left);
                //中序位置输出节点信息
                System.out.print(root.key+"->");
                inOrder(root.right);
            }
        }

        //后序遍历
        public void postOrder(Node root){
            if(root != null){
                postOrder(root.left);
                postOrder(root.right);
                //后序位置输出节点信息
                System.out.print(root.key+"->");
            }
        }

二叉树层次遍历(广度优先遍历)

使用队列作存放需要遍历的树节点,最开始将树的根放入队列中。在队列非空的情况下,取出队首的元素node , 然后将node的左右节点放入队列中去(如果有的话),重复这个步骤直到树中节点遍历完。

        //层次遍历
        public void levelOrder(Node root){
            Queue<Node> queue = new LinkedList<Node>();
            queue.add(root);
            while(!queue.isEmpty()){
                Node node = queue.poll();
                System.out.print(node.key+"->");
                if(node.left != null){
                    queue.add(node.left);
                }
                if(node.right != null){
                    queue.add(node.right);
                }
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值