算法基础之--二分搜索树(添加,删除,深度优先遍历,广度优先遍历)

这里写图片描述

package wck.sort;/**
 * Created on 18/9/10.
 */

import java.util.ArrayList;
import java.util.Queue;

/**
 * @program: demo
 * @description: 二分搜索树
 * @author: wck
 * @create: 2018-09-10 12:50
 **/
public class BST {

    /**
     * 节点类
     * @param <Key>
     * @param <Value>
     */
    private class Node<Key extends Comparable<Key>,Value> {
        //键值对的key
        private Key key;
        //键值对的value
        private Value value;
        //当前节点的左右节点
        private Node right,left;

        public Node(Node node){
            this.key = (Key) node.key;
            this.value = (Value) node.value;
            this.left = node.left;
            this.right = node.right;
        }


        public Node (Key key,Value value){
            this.key =key;
            this.value=value;
            right = left = null;
        }

        //根节点
        private Node root;
        //记录元素个数
        private int count;
        //默认构造函数
        public Node (){
            this.root =null;
            count = 0;
        }

        /**
         * 添加元素
         * @param key
         * @param value
         */
        public void insert(Key key,Value value){
            root = insert(root,key,value);
        }

        /**
         * 递归的条件为:否则会判断当前新加节点
         * 是不是比左子节点小,满足继续走左分支,如果当前加入节点比右子节点大则加入右分支;继续递归
         * @param node
         * @param key
         * @param value
         * @return
         */
        Node insert(Node node,Key key,Value value){

            //当前节点为空,新建节点
            if(node == null){
                count++;
                return new Node(key,value);
            }

            if(node.key == key)
                node.value = value;
            else if(key.compareTo((Key) node.key)<0)
                insert(node.left, key, value);
            else
                insert(node.right,key,value);

            return  node;
        };
        //是够包含当前元素
        boolean contain(Key key){
            return contain(root,key);
        }

        boolean contain(Node node,Key key){

            if(node == null){
                return false;
            }

            if(node.key == key)
                return true;
            else if(key.compareTo((Key) node.key) < 0)
                return  contain(node.left,key);
            else
                return  contain(node.right,key);
        }
        //查询元素
        Value search(Key key){
            return search(root,key);
        }

        Value search(Node node,Key key){

            if(node == null)
                return null;
            if(key.compareTo((Key) node.key) == 0)
                return (Value) node.value;
            else if (key.compareTo((Key) node.key) < 0)
                return search(node.left,key);
            else
                return search(node.right,key);

        }

        /** 前序遍历,中序遍历,后序遍历都是'深度优先'遍历;也就是遍历到最底部后再返回继续
         * //前序遍历 ---依次遍历
         * @param node
         */
        void preOder(Node node){
            if(node != null){
                System.out.println(node.key);
                preOder(node.left);
                preOder(node.right);
            }

        }

        //中序遍历 ---从小到大
        void inOrder(Node node){
            if(node != null){
                inOrder(node.left);
                System.out.println(node.key);
                inOrder(right);

            }
        }

        //后序遍历 ---将左右子数遍历完后,才释放自身;释放整个树
        void postOrder(Node node){
            if(node != null){
                postOrder(node.left);
                postOrder(right);
                System.out.println(node.key);

            }
        }

        //释放整个树实现--
        void destroy(Node node){
            destroy(node.left);
            destroy(right);
            node = null; //help GC
            count--;
        }

        //广度优先级遍历(层级遍历)
        void levelOrder(){
            Queue<Node> queue = (Queue) new ArrayList<Node>();
            queue.add(root);

            while(!queue.isEmpty()){
                //删除操作返回之前的元素
                Node remove = queue.remove();
                System.out.println(remove.key);

                if(remove.left != null)
                    queue.add(remove.left );
                if(remove.right != null)
                    queue.add(remove.right );
            }

        }

        // 返回以node为根的二分搜索树的最小键值所在的节点
        private Node minimum(Node node){
            if( node.left == null )
                return node;

            return minimum(node.left);
        }

        // 删除掉以node为根的二分搜索树中的最小节点
        // 返回删除节点后新的二分搜索树的根
        private Node removeMin(Node node){

            if( node.left == null ){

                Node rightNode = node.right;
                node.right = null;
                count --;
                return rightNode;
            }

            node.left = removeMin(node.left);
            return node;
        }

        // 删除掉以node为根的二分搜索树中的最大节点
        // 返回删除节点后新的二分搜索树的根
        private Node removeMax(Node node){

            if( node.right == null ){

                Node leftNode = node.left;
                node.left = null;
                count --;
                return leftNode;
            }

            node.right = removeMax(node.right);
            return node;
        }

        //二叉树删除元素
        Node remove(Key key){
            Node remove = remove(root, key);
            return  remove;
        }

        Node remove(Node node,Key key){

            //要是特么的为空才则返回,否则要是以下条件:1,2都不会返回
            if(node == null)
                return null;

            //1:比左子节点小
            if(key.compareTo((Key) node.left) <0){
                node.left = remove(node.left,key);
                return node;
            } else if(key.compareTo((Key) node.left) <0){
                node.left = remove(node.left,key);
                return node;
            //即 key == node.key
            }else{
                //左树为空
                if(node.left == null){
                    Node rightNode = node.right;
                    node.right = null;
                    count =count -1;  //自减一
                    return rightNode;
                }
                //右树为空
                if(node.right == null){
                    Node leftNode = node.left;
                    node.left = null;
                    count =count -1;
                    return leftNode;
                }
                //左右子树都不为空
                //找到当前节点,右子数中最小节点;或者左子树中最大的节点作为新的跟节点;
                Node successor = new Node(minimum(node.right));
                successor.right = node.right;
                successor.left = node.left;
                node = null;
                count --;
                return successor;
            }

        }
    }

}

猜你喜欢

转载自blog.csdn.net/qq_36866808/article/details/82591289