数据结构-二叉查找树

来源:互联网 发布:js删除指定id的tr 编辑:程序博客网 时间:2024/05/20 14:40

数组和链表表示的结构只是元素的顺序,而树是一种能够表示层次结构的数据结构。这里写图片描述
root节点为树的根节点,根下面还有很多子树,子树的根节点为root节点的儿子,这里写图片描述
一个节点的上节点为该节点的父节点,父节点包含多个子节点。没有子节点的节点称为叶子。一个节点到根节点唯一路径的距离叫做深度,节点到下面叶子的距离称为高。例如E节点的深度为1高为2。
二叉树是一种树,该树每个节点不能有多于两个子节点。
这里写图片描述
二叉树的平均深度为O(√N),对于二叉查找树的平均深度为O(logN).

二叉查找树

二叉查找树在查找中有重要应用。
二叉查找树
对于每个节点X,左子节点的值小于X,右子节点的值大于X。
二叉查找树是中抽象数据结构类型,具有一系列的操作。现在我们来自己实现一下这个二叉查找树。

package com.creat.binarytree;/** * Created by WHZ on 2017/8/11 0011. */public class BinarySearchTree<E extends Comparable<? super E>>{    private BinaryNode<E> root;    private static class BinaryNode<E>{        E element;        BinaryNode<E> left;        BinaryNode<E>  right;        BinaryNode(E element){            this.element = element;            this.left = null;            this.right = null;        }        BinaryNode(BinaryNode<E> left, E element, BinaryNode<E> right){            this.left = left;            this.element = element;            this.right = right;        }    }    public BinarySearchTree(){        root = null;    }    public void makeEmpty(){        root = null;    }    public boolean isEmpty(){        return (root == null);    }    public boolean contains(E x){        return contains(x,root);    }    private boolean contains(E x,BinaryNode<E> node){        if(node == null){            return false;        }        final int result = node.element.compareTo(x);        if(result > 0){            return contains(x, node.left);        }else if( result < 0){            return contains(x, node.right);        }else {            return true;        }    }    public void insert(E x){        root = insert(x , root);    }    private BinaryNode<E> insert(E x, BinaryNode<E> node){        if(node == null){            return new BinaryNode<E>(x);        }        int result = node.element.compareTo(x);        if(result > 0){            node.left = insert(x, node.left);        }else if(result < 0){            node.right = insert(x, node.right);        }else {            ;        }        return node;    }    public void remove(E x){        root = remove(x, root);    }    private BinaryNode<E>  remove(E x, BinaryNode<E> node){        if(node == null){            return null;        }        final int result = node.element.compareTo(x);        if(result > 0){            node.left = remove(x , node.left);        }else if( result < 0){            node.right = remove(x, node.right);        }else if(node.left != null && node.right != null){            node.element = findMin(node.right).element;            node.right = remove(node.element, node.right);        }else {            node = (node.right != null) ? node.right: node.left;        }        return node;    }    private BinaryNode<E> findMax(BinaryNode<E> node){        if(node != null){            while(node.right != null){                node = node.right;            }        }        return node;    }    private BinaryNode<E> findMin(BinaryNode<E> node){        if(node != null){            while(node.left != null){                node = node.left;            }        }        return node;    }    public void printTree(){        printTree(root);    }    private void printTree(BinaryNode<E> node){        if(node != null) {            printTree(node.left);            System.out.println(node.element);            printTree(node.right);        }    }}

我想contains方法和insert难度不大,最难的是remove;我们需要考虑多种情况,当需要删除的节点只有一个子节点的时候,我们只须将上一节点的指针指向该子节点,(如果没有子节点,那么情况也包含在内,相当于指针指向null)这里写图片描述
当有两个子节点的时候,那么一般情况下采取的策略是将右子树最小的值换到需要被删除的位置,再去递归删除这个最小值的节点,因为这个最小值的节点肯定没有左节点,所以递归最后肯定能在一种情况下结束。
这里写图片描述