二叉搜索树(二叉查找树,排序二叉树,有序二叉树)

定义

一棵空树,或者是具有下列性质的二叉树:

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

(3)左、右子树也分别为二叉排序树;

【注】:以上的三种定义在不同的数据结构教材中均有不同的定义方式 但是都是正确的 在开发时需要根据不 同的需求进行选择

【注2】:没有键值相等的结点。

实现

// 二叉搜索树类
public class BinarySearchTree{ 
    // 节点类
    private class Node{ 
        // 数据域
        int data; 
        // 右子树
        Node right; 
        // 左子树
        Node left; 
    }
    // 根节点    
    private Node root; 


//insert
    public void insert(int key){
        // 待插入的节点
        Node p = new Node(); 
        p.data = key;
        if (root == null){
            root = p;
        }else{
            Node parent = new Node();
            Node current = root;
            while (true){
                parent = current;
                if (key > current.data){
                    current = current.right; // 右子树
                    if (current == null){
                        parent.right = p;
                        return;
                    }
                }else {
                // 本程序没有做key出现相等情况的处理,暂且假设用户插入的节点值都不同
                    current = current.left; // 左子树
                    if (current == null){
                        parent.left = p;
                        return;
                    }
                }
            }
        }
    }
//delete
//寻找要删除节点的中序后继结点
    private Node getSuccessor(Node delNode){
        Node successorParent=delNode;
        Node successor=delNode;
        Node current=delNode.right;
        //用来寻找后继结点
        while(current!=null){
            successorParent=successor;
            successor=current;
            current=current.left;
        } 
        //如果后继结点为要删除结点的右子树的左子,需要预先调整一下要删除结点的右子树
        if(successor!=delNode.right) {
            successorParent.left=successor.right;
            successor.right=delNode.right;
        }
        return successor;
     }
     
    public boolean delete(int key){
        Node current = root;
        Node parent = new Node();
        boolean isRightChild = true;
        while (current.data != key)
            parent = current;
            if (key > current.data){
                current = current.right;
                isRightChild = true;
            }else{
                current = current.left;
                isRightChild = false;
            }
            // 没有找到要删除的结点
            if (current == null) return false; 
        // 此时current就是要删除的结点,parent为其父结点
        // 要删除结点为叶子结点
        if (current.right == null && current.left == null)  {
            if (current == root){
                root = null; // 整棵树清空
            }else{
                if (isRightChild)
                    parent.right = null;
                else
                    parent.left = null;
            }
            return true;
        }else if(current.left==null){
        //要删除结点有一个子结点
            if(current==root)
                root=current.right;
            else if(isRightChild)
                parent.right=current.right;
            else
                parent.left=current.right;
            return true;
        }else if(current.right==null){
            if(current==root)
                root=current.left;
            else if(isRightChild)
                parent.right=current.left;
            else
                parent.left=current.left;
            return true;
        }else{ 
         //要删除结点有两个子结点
         //找到要删除结点的后继结点
            Node successor=getSuccessor(current);   
            if(current==root)
                root=successor;
            else if(isRightChild)
                parent.right=successor;
            else
                parent.left=successor;
            
            successor.left=current.left;
            return true;
        }
    } 
    
    

//update


//select
     // 选择以何种方式遍历
    public void traverse(int traverseType){ 
        switch (traverseType){
        case 1:
            System.out.print("preOrder traversal ");
            preOrder(root);
            System.out.println();
            break;
        case 2:
            System.out.print("inOrder traversal ");
            inOrder(root);
            System.out.println();
            break;
        case 3:
            System.out.print("postOrder traversal ");
            postOrder(root);
            System.out.println();
            break;
        }
    }
    // 前序遍历,"中左右"
    public void preOrder(Node root){ 
        if (root != null){
            System.out.print(root.data + " ");
            preOrder(root.left);
            preOrder(root.right);
        }
    }
    
     // 中序遍历,"左中右"
    public void inOrder(Node root){
        if (root != null){
            inOrder(root.left);
            System.out.print(root.data + " ");
            inOrder(root.right);
        }
    }
     // 后序遍历,"左右中"
    public void postOrder(Node root){
        if (root != null){
            postOrder(root.left);
            postOrder(root.right);
            System.out.print(root.data + " ");
        }
    }
    // 从树中按照关键值查找元素
    public Node find(int key){ 
        Node current = root;
        while (current.data != key){
            if (key > current.data)
                current = current.right;
            else
                current = current.left;
            if (current == null) return null;
        }
        return current;
    }
    //输出节点的数据域
    public void show(Node node){    
        if(node!=null)
            System.out.println(node.data);
        else
            System.out.println("null");
    }
    public static void main(String[] args){
        BinarySearchTree tree = new BinarySearchTree();

        tree.insert(39);
        tree.insert(24);
        tree.insert(64);
        tree.insert(23);
        tree.insert(30);
        tree.insert(53);
        tree.insert(60);
        /**
         * 		    39
         * 		   /  \
         * 		 24    64
         * 		/  \  /
         *             23 30  53
         * 		        \
         * 			60
         * 
         */
        tree.traverse(1);
        //preOrder traversal 39 24 23 30 64 53 60 
        tree.traverse(2);
        //inOrder traversal 23 24 30 39 53 60 64 
        tree.traverse(3);
        //postOrder traversal 23 30 24 60 53 64 39 
        
        tree.show(tree.find(23));
        //23
        
        //tree.show(tree.find(60));
        //tree.show(tree.find(64));
        
        tree.delete(23);
        //tree.delete(60);
        //tree.delete(64);
        
        tree.show(tree.find(23));
        //
        
        //tree.show(tree.find(60));
        //tree.show(tree.find(64));
    }
}

Last updated