zoukankan      html  css  js  c++  java
  • 二叉排序树

    一、基本数据结构

    public class Node<T extends Comparable<T>>{
        private T value;
        private int height;
        private Node<T> left;
        private Node<T> right;
        public Node(T value) {
            this.value = value;
            this.height = 1;
            this.left = null;
            this.right = null;
        }
        public T getValue() {
            return value;
        }
        public void setValue(T value) {
            this.value = value;
        }
        public int getHeight() {
            return height;
        }
        public void setHeight(int height) {
            this.height = height;
        }
        public Node<T> getLeft() {
            return left;
        }
        public void setLeft(Node<T> left) {
            this.left = left;
        }
        public Node<T> getRight() {
            return right;
        }
        public void setRight(Node<T> right) {
            this.right = right;
        }
        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return this.value.toString();
        }
    }

    工具类函数

        public static <T extends Comparable<T>> Node<T> maximumNode(Node<T> root) {
            //求左子树最大值的前驱节点
            if(root == null) {
                return null;
            }
            Node<T> prev = root;
            Node<T> post = null;
            while(prev.getRight()!=null) {
                post = prev;
                prev = prev.getRight();
            }
            return post;
        }
        public static <T extends Comparable<T>> Node<T> minimumNode(Node<T> root) {
            //求右子树最小值的前驱节点
            if(root == null) {
                return null;
            }
            Node<T> prev = root;
            Node<T> post = null;
            while(prev.getLeft()!=null) {
                post = prev;
                prev = prev.getLeft();
            }
            return post;
        }
        public static <T extends Comparable<T>> T maximum(Node<T> root) {
            //求左子树最大值
            if(root == null) {
                return null;
            }
            Node<T> prev = root;
            Node<T> post = null;
            while(prev.getRight()!=null) {
                post = prev;
                prev = prev.getRight();
            }
            return prev.getValue();
        }
        public static <T extends Comparable<T>> T minimum(Node<T> root) {
            //求右子树最小值
            if(root == null) {
                return null;
            }
            Node<T> prev = root;
            Node<T> post = null;
            while(prev.getLeft()!=null) {
                post = prev;
                prev = prev.getLeft();
            }
            return prev.getValue();
        }
        public static <T extends Comparable<T>> int height(Node<T> node) {
            //求高度
            if(node == null) {
                return 0;
            }else {
                return node.getHeight();
            }
        }
        public static <T extends Comparable<T>> int maxHeight(Node<T> n1, Node<T> n2) {
            //求最大高度
            return height(n1)>height(n2)?height(n1):height(n2);
        }
        public static <T extends Comparable<T>> Node<T> rightRightRotation(Node<T> root){
            //左旋操作
            Node<T> node = root.getRight();
            root.setRight(node.getLeft());
            node.setLeft(root);
            root.setHeight(maxHeight(root.getLeft(),root.getRight())+1);
            node.setHeight(maxHeight(node.getLeft(),node.getRight())+1);
            return node;
        }
        public static <T extends Comparable<T>> Node<T> leftLeftRotation(Node<T> root){
            //右旋操作
            Node<T> node = root.getLeft();
            root.setLeft(node.getRight());
            node.setRight(root);
            root.setHeight(maxHeight(root.getLeft(),root.getRight())+1);
            node.setHeight(maxHeight(node.getLeft(),node.getRight())+1);
            return node;
        }
        public static <T extends Comparable<T>> Node<T> rightLeftRotation(Node<T> root){
            //先右旋再左旋
            root.setRight(leftLeftRotation(root.getRight()));
            return rightRightRotation(root);
        }
        public static <T extends Comparable<T>> Node<T> leftRightRotation(Node<T> root){
            //先左旋再右旋
            root.setLeft(rightRightRotation(root.getLeft()));
            return leftLeftRotation(root);
        }

    二、普通二叉排序树

    1、二叉排序树的insert(非递归)

        public static <T extends Comparable<T>> Node<T> insert(Node<T> root, T value){
            Node<T> node = new Node<T>(value);
            if(root == null) {
                return node;
            }
            int temp = 0;
            Node<T> prev = root;
            while(prev!=null) {
                temp = prev.getValue().compareTo(value);
                if(temp == 0) {
                    return root;
                }else if(temp == 1) {
                    if(prev.getLeft()==null) {
                        prev.setLeft(node);
                    }
                    prev = prev.getLeft();
                }else {
                    if(prev.getRight()==null) {
                        prev.setRight(node);
                    }
                    prev = prev.getRight();
                }
            }
            return root;
        }

    2、二叉排序树的insert(递归)

    public static <T extends Comparable<T>> Node<T> insert(Node<T> root, T value){
            if(root == null) {
                Node<T> node = new Node<T>(value);
                return node;
            }
            int temp = root.getValue().compareTo(value);
            if(temp == 0) {
                return root;
            }else if(temp == 1) {
                root.setLeft(insert(root.getLeft(), value));
            }else {
                root.setRight(insert(root.getRight(), value));
            }
            return root;
        }

    3、二叉排序树的insert(包含有height)

        public static <T extends Comparable<T>> Node<T> insert(Node<T> root, T value){
            if(root == null) {
                Node<T> node = new Node<T>(value);
                return node;
            }
            int temp = root.getValue().compareTo(value);
            if(temp == 0) {
                return root;
            }else if(temp == 1) {
                root.setLeft(insert(root.getLeft(),value));
                root.setHeight(maxHeight(root.getLeft(), root.getRight())+1);
            }else {
                root.setRight(insert(root.getRight(),value));
                root.setHeight(maxHeight(root.getLeft(), root.getRight())+1);
            }
            return root;
        }

    4、二叉排序树的删除(递归)

        public static <T extends Comparable<T>> Node<T> delete(Node<T> root, T value){
            if(root == null) {
                return null;
            }
            int temp = root.getValue().compareTo(value);
            if(temp == 0) {//这里取的是root左子树最右边的节点(即最大的节点);也可以取root右子树最左边的节点(即最小的节点)
                if(root.getLeft()==null||root.getRight()==null) {
                    return root.getLeft()==null?root.getRight():root.getLeft();
                }else {
                    Node<T> left = root.getLeft();
                    Node<T> post = maximumNode(left);
                    if(post == null) {
                        root.setValue(left.getValue());
                        root.setLeft(left.getLeft());
                    }else {
                        root.setValue(post.getRight().getValue());
                        post.setRight(post.getRight().getLeft());
                    }
                }
            }else if(temp == 1) {
                root.setLeft(delete(root.getLeft(), value));
            }else {
                root.setRight(delete(root.getRight(), value));
            }
            return root;
        }

    三、AVL树(AVL树的根节点会随着insert和delete操作而改变,这一点测试的时候要注意,要随时更新根节点)

    1、AVL树的insert操作

        public static <T extends Comparable<T>> Node<T> insertAvl(Node<T> root, T value){
            if(root == null) {
                Node<T> node = new Node<T>(value);
                return node;
            }
            int temp = root.getValue().compareTo(value);
            if(temp == 0) {
                return root;
            }else if(temp == 1) {
                root.setLeft(insertAvl(root.getLeft(),value));
                if(height(root.getLeft())-height(root.getRight())==2) {
                    Node<T> node = root.getLeft();
                    if(height(node.getRight())>height(node.getLeft())) {
                        root = leftRightRotation(root);
                    }else {
                        root = leftLeftRotation(root);
                    }
                }
                
            }else {
                root.setRight(insertAvl(root.getRight(),value));
                if(height(root.getRight())-height(root.getLeft())==2) {
                    Node<T> node = root.getRight();
                    if(height(node.getLeft())>height(node.getRight())) {
                        root = rightLeftRotation(root);
                    }else {
                        root = rightRightRotation(root);
                    }
                }
            }
            root.setHeight(maxHeight(root.getLeft(), root.getRight())+1);
            return root;
        }

    2、AVL树的delete操作

        public static <T extends Comparable<T>> Node<T> avlDelete(Node<T> root, T value){
            if(root == null) {
                return null;
            }
            int temp = root.getValue().compareTo(value);
            if(temp == 0) {//这里取的是root左子树最右边的节点(即最大的节点);也可以取root右子树最左边的节点(即最小的节点)
                if(root.getLeft()==null||root.getRight()==null) {
                    return root.getLeft()==null?root.getRight():root.getLeft();
                }else {
                    if(height(root.getLeft())>height(root.getRight())) {
                        Node<T> left = root.getLeft();
                        T max = maximum(left);
                        root.setValue(max);
                        root.setLeft(avlDelete(root.getLeft(), max));
                    }else {
                        Node<T> right = root.getRight();
                        T min = minimum(right);
                        root.setValue(min);
                        root.setRight(avlDelete(root.getRight(), min));
                    }
                }
            }else if(temp == 1) {
                root.setLeft(avlDelete(root.getLeft(), value));
                if(height(root.getRight())-height(root.getLeft())==2) {
                    Node<T> node = root.getRight();
                    if(height(node.getLeft())>height(node.getRight())) {
                        root = rightLeftRotation(root);
                    }else {
                        root = rightRightRotation(root);
                    }
                }
            }else {
                root.setRight(avlDelete(root.getRight(), value));
                if(height(root.getLeft())-height(root.getRight())==2) {
                    Node<T> node = root.getLeft();
                    if(height(node.getRight())>height(node.getLeft())) {
                        root = leftRightRotation(root);
                    }else {
                        root = leftLeftRotation(root);
                    }
                }
            }
            root.setHeight(maxHeight(root.getLeft(), root.getRight())+1);
            return root;
        }

    参考文献

    AVL树漫画:http://www.sohu.com/a/270452030_478315

    AVL树代码:https://www.cnblogs.com/skywang12345/p/3577479.html

  • 相关阅读:
    use paramiko to connect remote server and execute command
    protect golang source code
    adjust jedi vim to python2 and python3
    install vim plugin local file offline
    add swap file if you only have 1G RAM
    datatables hyperlink in td
    django rest framework custom json format
    【JAVA基础】网络编程
    【JAVA基础】多线程
    【JAVA基础】String类的概述和使用
  • 原文地址:https://www.cnblogs.com/erdanyang/p/11009198.html
Copyright © 2011-2022 走看看