欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

二叉树:二叉搜索树 博客分类: Tree  

程序员文章站 2024-02-04 16:27:52
...
    所谓二叉树,就是一个节点最多只能有两个子节点,而二叉搜索树就是一个经典并简单的二叉树.规则是一个节点的左子节点一定比自己小,右子节点一定大于等于自己(当然也可以反过来).在树基本平衡的时候插入,搜索和删除速度都很快,时间复杂度为O(logN).但是,如果插入的是有序的数据,那效率就会变成O(N),在这个时候,树其实变成了一个链表.

tree代码:
public class Tree {
    private Node root;
    
    /**
     * 插入节点
     * @param data 
     */
    public void insert(int data){
        Node node = new Node(data);
        
        if(this.root == null){
            this.setRoot(node);
            return;
        }
        
        Node current = this.root;
        
        while(true){
            if(current.getData() > data){
                if(current.hasLeft()){
                    current = current.getLeft();
                }else{
                    current.setLeft(node);
                    return;
                }
            }else if(current.getData() < data){
                if(current.hasRight()){
                    current = current.getRight();
                }else{
                    current.setRight(node);
                    return;
                }
            }else{
                return;
            }
        }
    }
    
    /**
     * 删除节点
     * @param key 
     */
    public void remove(int key){
        Node node = this.findNode(key);
        
        if(node == null){
            return;
        }
        
        Node parent = node.getParent();
        
        //要删除的节点没有子节点
        if(!node.hasLeft() && !node.hasRight()){
            if(parent == null){
                this.setRoot(null);
            }else if(node.isLeft()){
                parent.setLeft(null);
            }else{
                parent.setRight(null);
            }
        //要删除的节点只有一个子节点
        }else if(!node.hasRight() || !node.hasLeft()){
            Node child = node.hasLeft() ? node.getLeft() : node.getRight();
            
            if(parent == null){
                this.setRoot(child);
            }else if(node.isLeft()){
                parent.setLeft(child);
            }else{
                parent.setRight(child);
            }
        //要删除的节点有两个子节点
        }else{
            Node successor = this.getSuccessor(node);
            
            if (parent == null) {
                this.setRoot(successor);
            } else if (node.isLeft()) {
                parent.setLeft(successor);
            } else {
                parent.setRight(successor);
            } 
        }
    }
    
    /**
     * 查找
     * @param key 
     */
    public void find(int key){
        Node node = this.findNode(key);
        
        if(node != null){
            System.out.println("node data is : " + node.getData());
        }
    }
    
    /**
     * 查找节点
     * @param key
     * @return 
     */
    private Node findNode(int key){
        Node current = this.root;
        
        while(current.getData() != key){
            if(current.getData() > key){
                if(current.hasLeft()){
                    current = current.getLeft();
                }else{
                    return null;
                }
            }else if(current.getData() < key){
                if(current.hasRight()){
                    current = current.getRight();
                }else{
                    return null;
                }
            }
        }
        
        return current;
    }
    
    /**
     * 找到继任节点,找出删除节点中右树最小的节点,如果删除节点的右节点
     * 没有子节点,则返回null
     * @param node
     * @return 
     */
    private Node getSuccessor(Node node){
        Node current = node.getRight();
        
        while(current.hasLeft()){
            current = current.getLeft();
        }
        
        if(node.getRight() != current){
            Node parent = current.getParent();
            
            if(current.hasRight()){
                parent.setLeft(current.getRight());
            }else{
                parent.setLeft(null);
            }
            
            current.setRight(node.getRight());
        }
        
        current.setLeft(node.getLeft());
        
        return current;
    }
    
    private void setRoot(Node node){
        this.root = node;
        
        if(node != null){
            node.setParent(null);
        }
    }
}


node代码:
public class Node {
    private int data;
    private Node left;
    private Node right;
    private Node parent;

    public Node(int data){
        this.data = data;
    }
    
    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
        
        if(this.left != null){
            this.left.parent = this;
        }
    }

    public Node getParent() {
        return parent;
    }

    public void setParent(Node parent) {
        this.parent = parent;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
        
        if(this.right != null){
            this.right.parent = this;
        }
    }
    
    public boolean hasRight(){
        return this.right != null;
    }
    
    public boolean hasLeft(){
        return this.left != null;
    }
    
    public boolean isRoot(){
        return this.parent == null;
    }
    
    public boolean isRight(){
        return this.parent.right == this;
    }
    
    public boolean isLeft(){
        return this.parent.left == this;
    }
}