• 二分搜索树


    package BST;

    import java.util.LinkedList;
    import java.util.Queue;

    public class BST<Key extends Comparable<Key>,Value>{

    private class Node{ //节点的构造是keyvalue对应,外加上一个左右孩子节点
    private Key key;
    private Value value;
    private Node left;
    private Node right;
    public Node(Key key,Value value)
    {
    this.key=key;
    this.value=value;
    this.left=null;
    this.right=null;
    }
    public Node(Node node)    //第二种构造方法,直接用另一个节点进行复制
    {
    this.key=node.key;
    this.value=node.value;
    this.left=node.left;
    this.right=node.right;
    }
    }

    private Node root; //根节点
    private int count; //节点数量

    public BST() //默认构造一颗空的二分搜索树
    {
    Node root=null;
    count=0;
    }

    public int size()
    {
    return count;
    }
    public boolean isEmpty()
    {
    return count==0;
    }

    public void insert(Key key,Value value) //插入一个元素,找到合适的位置插入
    {
    root= insert(root,key,value);
    }
    public boolean contain(Key key) //查找是否包含这个元素,包含返回true,否则返回false;
    {
    return contain(root,key); //递归调用

    }
    public Value search(Key key) //查找是否有这个元素,找到了返回这个元素key对应的value值,不然返回null
    {
    return search(root,key); //递归调用
    }
    public void preOrder() //先序遍历
    {
    perOrder(root);
    }
    public void inOrder() //中序遍历
    {
    inOrder(root);
    }
    public void postOrder() //后序遍历
    {
    postOrder(root);
    }

    public void levelOrder() //二叉树的层序遍历,
    {
    Queue<Node> q=new LinkedList<>(); //利用一个队列,每次取出一个节点,入队,取出它,操作,再将左右孩子节点入队列
    q.add(root);
    while(!q.isEmpty())
    {
    Node node = q.remove();
    System.out.println(node.key);
    if(node.left!=null)
    q.add(node.left);
    if(node.right!=null)
    q.add(node.right);
    }
    }
    // 寻找二分搜索树的最小的键值
    public Key minimum(){
    assert count != 0;
    Node minNode = minimum( root );
    return minNode.key;
    }

    // 寻找二分搜索树的最大的键值
    public Key maximum(){
    assert count != 0;
    Node maxNode = maximum(root);
    return maxNode.key;
    }

    public void removeMin()
    {
    if(root!=null)
    {
    root=removeMin(root);
    }
    }

    public void removeMax()
    {
    if(root!=null)
    root=removeMax(root);
    }
    public void remove(Key key)
    {
    root=remove(root,key);
    }

    private Node remove(Node node, Key key) {
    if(node==null)
    return null;
    if(key.compareTo(node.key)<0)
    {
    node.left=remove(node.left,key);
    return node;

    }
    else if(key.compareTo(node.key)>0)
    {
    node.right=remove(node.right,key);
    return node;
    }
    else
    {
    if(node.left==null)
    {
    Node rightNode=node.right;
    node.right=null;
    count--;
    return rightNode;
    }
    else if(node.right==null)
    {
    Node leftNode=node.left;
    node.left=null;
    count--;
    return leftNode;
    }
    else //左右孩子都不为空
    {
    Node successor=new Node(minimum(node.right));
    count++;
    successor.right=removeMin(node.right);
    successor.left=node.left;
    node.left=null;
    node.right=null;
    count--;
    return successor;
    }
    }

    }

    // 删除掉以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为根的二分搜索树中的最小节点
    // 返回删除节点后新的二分搜索树的根,始终返回的是每一层的根节点,对于被删除的那个节点,要返回的也是对于那一层来说的根节点,
    // 所以需要把新节点当作根节点返回
    private Node removeMin(Node node)
    {
    if(node.left==null)
    {
    Node rightNode=node.right;
    node.right=null;
    count--;
    return rightNode;
    }
    else
    {
    node.left=removeMin(node.left);
    }
    return node;
    }
    // 返回以node为根的二分搜索树的最小键值所在的节点
    private Node minimum(Node node){
    if( node.left == null )
    return node;

    return minimum(node.left);
    }

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

    return maximum(node.right);
    }

    private void postOrder(Node node) {
    if(node==null)
    return ;
    else
    {
    postOrder(node.left);
    postOrder(node.right);
    System.out.println(node.key);
    }
    }

    private void inOrder(Node node) {
    if(node==null)
    return ;
    else{
    inOrder(node.left);
    System.out.println(node.key);
    inOrder(node.right);
    }
    }

    private void perOrder(Node node) {
    if(node!=null)
    {
    System.out.println(node.key);
    perOrder(node.left);
    perOrder(node.right);
    }
    }

    private Value search(Node node, Key key) {
    if(node==null) //找到底了,node为空,说明没找到这个元素,直接返回null
    return null;
    if(key.compareTo(node.key)==0) //找到了key,就是node,直接返回nodevalue
    {
    return node.value;
    }
    else if(key.compareTo(node.key)<0) //小于,继续递归调用查找node的左孩子
    {
    return search(node.left,key);
    }
    else //大于,找node的右孩子
    return search(node.right,key);

    }

    private boolean contain(Node node, Key key) {
    if(node==null)
    return false;
    if(key.compareTo(node.key)==0)
    {
    return true;
    }
    else if(key.compareTo(node.key)<0)
    {
    return contain(node.left,key);
    }
    else
    return contain(node.right,key);
    }

    private Node insert(Node root, Key key, Value value) { //递归来完成插入操作
    if(root==null)
    {
    return new Node(key,value);
    }

    if(key.compareTo(root.key)==0)
    {
    root.value=value;
    }
    else if(key.compareTo(root.key)<0)
    {
    root.left=insert(root.left, key,value);
    }
    else
    root.right = insert(root.right, key, value);
    return root;
    }

    }
  • 相关阅读:
    【技巧总结】公开漏洞学习
    【 Keepalived 】Nginx or Http 主-主模式
    【 Keepalived 】Nginx or Http 主-备模式
    【 转 】Keepalived工作原理
    【 总结 】crontab 使用脚本及直接获取HTTP状态码
    【 总结 】linux中test命令详解
    【 总结 】Tcp Keepalive 和 HTTP Keepalive 详解
    【 Linux 】I/O工作模型及Web服务器原理
    【 Ngnix 】配置路径转发至后端Apache多台虚拟主机
    【 Linux】脚本导入格式
  • 原文地址:https://www.cnblogs.com/cold-windy/p/11228480.html
Copyright © 2020-2023  润新知