zoukankan      html  css  js  c++  java
  • 二分搜索树

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

    }
  • 相关阅读:
    权益证明,一些观点
    【转】量化去中心化
    论社会信任网络中货币的债权属性和关于去中心化货币网络协议的建议
    加密经济学应用的机制设计
    区块链知识体系
    WordPress发布文章/页面时自动添加默认的自定义字段
    WordPress发布文章/页面时自动添加默认的自定义字段
    WordPress发布文章/页面时自动添加默认的自定义字段
    WordPress发布文章/页面时自动添加默认的自定义字段
    Spring源码学习——自定义标签
  • 原文地址:https://www.cnblogs.com/cold-windy/p/11228480.html
Copyright © 2011-2022 走看看