BST

启发式搜索算法有点像广度优先搜索,不同的是,它会优先顺着有启发性和具有特定信息的节点搜索下去,这些节点可能是到达目标的最好路径。 我们称这个过程为最优(best-first)或启发式搜索。 下面是其基本思想: 1) 假定有一个启发式(评估)函数ˆf ,可以帮助确定下一个要扩展的最优节点, 我们采用一个约定,即ˆf的值小表示找到了好的节点。 这个函数基于指定问题域的信息,它是状态描述的一个实数值函数。 2) 下一个要扩展的节点n是ˆf(n)值最小的节点(假定节点扩展产生一个节点的所有后 继)。 3) 当下一个要扩展的节点是目标节点时过程终止。

节点类

package com.landry.algorithm;

public class BinaryNode<T> {
    T data;
    BinaryNode<T> left;
    BinaryNode<T> right;

    public BinaryNode(T data) {
        this(data, null, null);
    }

    public BinaryNode(T data, BinaryNode<T> left, BinaryNode<T> right) {
        this.data = data;
        this.left = left;
        this.right = right;
    }

    public BinaryNode() {
        data = null;
        this.left = left;
        this.right = right;
    }
}

BST类。主要实现了remove方法。

package com.landry.algorithm;

/**
 * Java实现二叉查找树
 *
 * @param <T>
 * @author Kiritor
 */
public class BinarySearchTree<T extends Comparable<? super T>> {

    /**
     * 结点数据结构
     */
    private BinaryNode<T> rootTree;

    /**
     * 构造一颗空的二叉查找树
     */
    public BinarySearchTree() {
        rootTree = null;
    }

    /**
     * 清空二叉查找树
     */
    public void clear() {
        rootTree = null;
    }

    /**
     * 判断是否为空
     */
    public boolean isEmpty() {
        return rootTree == null;
    }

    /**
     * 查找指定的元素,默认从
     * 根结点出开始查询
     */
    public boolean contains(T t) {
        return contains(t, rootTree);

    }

    /**
     * 找到二叉查找树中的最小值
     */
    public T findMin() {
        if (isEmpty()) {
            System.out.println("二叉树为空");
            return null;
        } else
            return findMin(rootTree).data;

    }

    /**
     * 找到二叉查找树中的最大值
     */
    public T findMax() {
        if (isEmpty()) {
            System.out.println("二叉树为空");
            return null;
        } else
            return findMax(rootTree).data;
    }

    /**
     * 插入元素
     */
    public void insert(T t) {
        rootTree = insert(t, rootTree);
    }

    /**
     * 删除元素
     */
    public void remove(T t) {
//        rootTree = remove(t, rootTree);
        //exceptions
        BinaryNode<T> temp = rootTree;
        //使用哨兵,避免要删除的是根节点。
        BinaryNode<T> temp_parent = new BinaryNode<T>(null,rootTree,null);
        boolean isLeft = true;
        while (null != temp) {
            if(t.compareTo(temp.data) < 0) {
                temp_parent = temp;
                isLeft = true;
                temp = temp.left;
            } else if (t.compareTo(temp.data) > 0) {
                temp_parent = temp;
                isLeft = false;
                temp = temp.right;
            } else {
                break;
            }
        }
        //not found.
        if (null == temp) {
            return ;
        }
        if (null == temp.left || null == temp.right) {
            BinaryNode<T> node = null == temp.left ? temp.right : temp.left;
            if(true == isLeft) {
                temp_parent.left = node;
            } else {
                temp_parent.right = node;
            }
        } else {
            //寻找最小的节点,取出其内容复制给temp ,并删除掉这个最小节点
           BinaryNode<T> node = temp.right;
           if(null == node.left) {
               //temp.right最小
               temp.data = temp.right.data;
               temp.right = temp.right.right;
           } else {
               while (null != node.left && null != node.left.left) {
                   node = node.left;
               }
               //node.left not null but node.left.left null
               //so node.left 最小
               temp.data = node.left.data;
               node.left = node.left.right;
           }

        }
        rootTree = temp_parent.left;
    }

    /**
     * 从某个结点出开始查找元素,node是一颗BST的根结点
     */
    private boolean contains(T t, BinaryNode<T> node) {
        if (node == null)
            return false;
        int result = t.compareTo(node.data);
        if (result > 0)
            return contains(t, node.right);
        else if (result < 0)
            return contains(t, node.left);
        else
            return true;
    }

    /**
     * 查询出最小元素所在的结点,node是一颗BST的根结点
     */
    private BinaryNode<T> findMin(BinaryNode<T> node) {
        /**
         *
         if(node==null)
         return null;
         else if(node.left==null)
         return node;
         return findMin(node.left);//递归查找
         */
        if (null == node) {
            return null;
        }
        while (null != node.left) {
            node = node.left;
        }
        return node;
    }

    /**
     * 查询出最大元素所在的结点,node是一颗BST的根结点
     */
    private BinaryNode<T> findMax(BinaryNode<T> node) {
        if (node != null) {
            while (node.right != null)
                node = node.right;
        }
        return node;
    }

    /**
     * 在某个位置开始判断插入元素,node是一颗BST的根结点
     */
    private BinaryNode<T> insert(T t, BinaryNode<T> node) {
        if (node == null) {
            //新构造一个二叉查找树
            return new BinaryNode<T>(t, null, null);
        }
        int result = t.compareTo(node.data);
        if (result < 0)
            node.left = insert(t, node.left);
        else if (result > 0)
            node.right = insert(t, node.right);
        else
            ;//doNothing
        return node;
    }

    /**
     * 在某个位置开始判断删除某个结点,node是一颗BST的根结点
     */
    /*private BinaryNode<T> remove(T t, BinaryNode<T> node) {
        if (node == null)
            return node;//没有找到,doNothing
        int result = t.compareTo(node.data);
        if (result > 0)
            node.right = remove(t, node.right);
        else if (result < 0)
            node.left = remove(t, node.left);
        else if (node.left != null && node.right != null) {
            node.data = findMin(node.right).data;
            node.right = remove(node.data, node.right);
        } else
            node = (node.left != null) ? node.left : node.right;
        return node;

    }*/

}