文章首发于此,BST是后面自平衡二叉树AVL树,B树等数据结构的基础,所以理解BST的基本性质和操作很有必要,如果读者对BST不是很了解可以查下wiki或者是参考严蔚敏的《数据结构与算法》或者《算法导论》,对于该数据结构有较详细解释,下面是我查询资料实现的Java版本。
package com.mars.search; public class BinarySeachTree { private Node mRoot; private Node getRoot() { return mRoot; } public int search(Node root, int key) { if (root == null) { return 0xffffffff; } if (key < root.key) { return search(root.leftNode, key); } if (key > root.key) { return search(root.rightNode, key); } else { return key; } } public void insert(int data) { if (mRoot == null) { mRoot = new Node(data, null, null); // mRoot.key = data; } Node root = mRoot; while (root != null) { if (data == root.key) { return; } else if (data < root.key) { if (root.leftNode == null) { root.leftNode = new Node(data, null, null); return; } else { root = root.leftNode; } } else { if (root.rightNode == null) { root.rightNode = new Node(data, null, null); return; } else { root = root.rightNode; } } } } /* * http://courses.csail.mit.edu/6.006/spring11/rec/rec03.pdf Description: * Remove the node x from the binary search tree, making the necessary * adjustments to the binary search tree to maintain its properties. (Note * that this operation removes a specified node from the tree. If you wanted * to delete a key k from the tree, you would have to first call find(k) to * find the node with key k and then call delete to remove that node) Case 1: * x has no children. Just delete it (i.e. change parent node so that it * doesn’t point to x) Case 2: x has one child. Splice out x by linking x’s * parent to x’s child Case 3: x has two children. Splice out x’s successor * and replace x with x’s successor * * BST删除分析可以看这里 http://webdocs.cs.ualberta.ca/~holte/T26/del-from-bst.html */ public boolean delete(int key) { Node root = deleteNode(this.mRoot, key); if (root != null) { return true; } return false; } /** * * 删除有左右子树节点的时候其实等价于:1将右子树的最左叶子节点的值覆盖要删除节点的值, * 然后删除右子树最左叶子节点。 递归的过程中找到删除节点然后将右子树的最左子叶子节点的 * 值赋给删除节点,然后删除右子树的最左叶子节点。这步在递归退出的时候就做了,如果想不 * 通可以细细的看下第一个if语句 * * */ private Node deleteNode(Node root, int key) { if (key < root.key) { if (root.leftNode != null) { root.leftNode = deleteNode(root.leftNode, key); } else { return null; } } else if (key > root.key) { if (root.rightNode != null) { root.rightNode = deleteNode(root.rightNode, key); } else { return null; } } else { if (root.leftNode == null) { root = root.rightNode; } else if (root.rightNode == null) { root = root.leftNode; } else { Node newRoot = findMin(root); root.key = newRoot.key; // 此步递归调用相当于把右子树的最左子树的左叶子给删了,因为递归退出的时候leftNode = null; //如果Node的結構里有指向parent的引用,刪除會方便些 root.rightNode = deleteNode(root.rightNode, root.key); } } return root; } // 左子树的最右叶子节点 private Node findMin(Node root) { Node newRoot = root.rightNode; while (newRoot.leftNode != null) { newRoot = newRoot.leftNode; } return newRoot; } public void travel(Node root) { Node node = root; if (node == null) { return; } travel(node.leftNode); System.out.print(node.key + " "); travel(node.rightNode); } public static class Node { int key; Node leftNode; Node rightNode; Node(int key, Node left, Node right) { this.key = key; this.leftNode = left; this.rightNode = right; } } public static void main(String[] args) { BinarySeachTree bst = new BinarySeachTree(); int[] a = { 0, 4, 3, 2, 5, 1, 7, 6, 8, 9 }; for (int i : a) { bst.insert(i); } bst.travel(bst.getRoot()); int i = bst.search(bst.getRoot(), 3); System.out.println("\nsearch :" + i); System.out.println("after delete:"); bst.delete(4); bst.travel(bst.getRoot()); } }
参考资料http://en.wikipedia.org/wiki/Binary_search_tree
数据结构与算法