算法导论示例-BinarySearchTree

来源:互联网 发布:淘宝快递不送货退款 编辑:程序博客网 时间:2024/06/05 19:32
/** * Introduction to Algorithms, Second Edition  * 12 Binary Search Trees * @author 土豆爸爸 *  */import java.util.ArrayList;import java.util.List;public class BinarySearchTree {    /**     * 数据节点     */    public static class Node {        int key;        Node parent; //父节点        Node left; //左子节点        Node right; //右子节点                public Node(int key) {            this.key = key;        }    }        private Node root;        /**     * 采用递归法查找键值为k的节点。     * @param k 节点的键值     * @return 返回键值为k的节点     */    public Node search(int k) {        return search(root, k);    }        /**     * 采用递归法查找键值为k的节点。     * @param x 当前节点     * @param k 节点的键值     * @return 返回键值为k的节点     */    private Node search(Node x, int k) {        if(x == null || k == x.key) {            return x;        } else if(k < x.key) {            return search(x.left, k);        } else {            return search(x.right, k);        }    }        /**     * 采用迭代法查找键值为k的节点。     * @param x 当前节点     * @param k 节点的键值     * @return 返回键值为k的节点     */    public Node iterativeSearch(int k) {        return iterativeSearch(root, k);    }        /**     * 采用迭代法查找键值为k的节点。     * @param x 当前节点     * @param k 节点的键值     * @return 返回键值为k的节点     */    private Node iterativeSearch(Node x, int k) {        while(x != null && k != x.key) {            if(k < x.key) {                x = x.left;            } else {                x = x.right;            }        }        return x;    }        /**     * 返回树的最小键值的节点。     * @return 最小键值的节点     */    public Node minimum() {        return minimum(root);    }        /**     * 返回树的最小键值的节点。     * @param x 当前节点     * @return 最小键值的节点     */    private Node minimum(Node x) {        while(x.left != null) {            x = x.left;        }        return x;    }        /**     * 返回树的最大键值的节点。     * @return 最大键值的节点     */    public Node maximum() {        return maximum(root);    }        /**     * 返回树的最大键值的节点。     * @param x 当前节点     * @return 最大键值的节点     */    private Node maximum(Node x) {        while(x.right != null) {            x = x.right;        }        return x;    }        /**     * 返回指定节点x的后继节点。     * @param x 当前节点     * @return x的后继节点;如果x具有最大键值,返回null     */    public Node successor(Node x) {        if(x.right != null) {            return minimum(x);        }        Node y = x.parent;        while(y != null && x == y.right) {            x = y;            y = y.parent;        }        return y;    }        /**     * 返回指定节点x的前驱节点。     * @param x 当前节点     * @return x的前驱节点;如果x具有最小键值,返回null     */    public Node predecessor(Node x) {        if(x.left != null) {            return maximum(x);        }        Node y = x.parent;        while(y != null && x == y.left) {            x = y;            y = y.parent;        }        return y;    }        /**     * 插入节点。     * @param z 待插入节点     */    public void insert(Node z) {        Node y = null; //当前节点的父节点        Node x = root; //当前节点        while(x != null) { //迭代查寻z应该所在的位置            y = x;            if(z.key < x.key) {                x = x.left;            } else {                x = x.right;            }        }        z.parent = y;        if(y == null) {             root = z; //如果没有父节点,则插入的节点是根节点。        } else if(z.key < y.key) {            y.left = z;        } else {            y.right = z;        }    }        /**     * 删除节点。     * @param z 待删除节点     */    public Node delete(Node z) {        Node y = null;        Node x = null;        if (z.left == null || z.right == null) {            y = z;        } else {            y = successor(z);        }        if (y != null) {            x = y.left;        } else {            x = y.right;        }        if (x != null) {            x.parent = y.parent;        }        if (y.parent == null) {            root = x;        } else if (y == y.parent.left) {            y.parent.left = x;        } else {            y.parent.right = x;        }        if (y != z) { //如果z包含两个子节点,用y替换z的位置            y.parent = z.parent;            if (z == z.parent.left) {                z.parent.left = y;            } else {                z.parent.right = y;            }            y.left = z.left;            y.right = z.right;        }        return y;    }        /**     * 中序历遍。即从小到大排序。     * @return 返回已排序的节点列表     */    public List<Node> inorderWalk() {        List<Node> list = new ArrayList<Node>();        inorderWalk(root, list);        return list;    }        /**     * 中序历遍。     * @param x 当前节点     * @param list 历遍结果存储在list中     */    private void inorderWalk(Node x, List<Node> list) {        if(x != null) {            inorderWalk(x.left, list);            list.add(x);            inorderWalk(x.right, list);        }    }}import java.util.List;import junit.framework.TestCase;public class BinarySearchTreeTest extends TestCase {    public void testLinkedList() {        BinarySearchTree tree = new BinarySearchTree();        // 插入100个随机节点        for (int i = 0; i < 100; i++) {            int key = (int) (Math.random() * 1000);            if (tree.search(key) == null) {                tree.insert(new BinarySearchTree.Node(key));            }        }        verifyOrdered(tree.inorderWalk());                BinarySearchTree.Node node = null;        for (int i = 0; i < 1000; i++) {            node = tree.search(i);            if (node != null) {                break;            }        }        assertNotNull(node);        tree.delete(node);        assertEquals(null, tree.search(node.key));                verifyOrdered(tree.inorderWalk());    }        private boolean verifyOrdered(List<BinarySearchTree.Node> list) {        for (int i = 1; i < list.size(); i++) {            if (list.get(i - 1).key > list.get(i).key) {                return false;            }        }        return true;    }}