标签:
/** * 树节点 */ public class TreeNode { int key;//节点的数值 TreeNode leftChild;//左子节点 TreeNode rightChild;//右子节点 TreeNode parent;//父节点 public TreeNode(int key,TreeNode leftChild,TreeNode rightChild,TreeNode parent){ this.key=key; this.leftChild=leftChild; this.rightChild=rightChild; this.parent=parent; } public int getKey() { return key; } public String toString(){ String leftkey = (leftChild==null?"":String.valueOf(leftChild.key)); String rightkey = (rightChild==null?"":String.valueOf(rightChild.key)); return "("+leftkey+","+key+","+rightkey+")"; } }
package test4; import java.util.ArrayList; import java.util.List; public class BinarySearchTree { //根节点 TreeNode root = null; //遍历节点列表 List<TreeNode> list = new ArrayList<TreeNode>(); /** * 判断二叉树是否为空 * @return */ public boolean isEmpty(){ if(null==root){ return true; } return false; } /** * search: 在二叉查找树中查询给定关键字 * @param key */ public TreeNode search(int key){ TreeNode pNode = root; while(pNode!=null&&pNode.key!=key){ if(key<pNode.key){ pNode=pNode.leftChild; }else{ pNode=pNode.rightChild; } } return pNode; } /** * 获取二叉查找树中的最小关键字结点 * @return * @throws Exception */ public TreeNode minNode(TreeNode node) throws Exception{ if(node==null){ throw new Exception("null tree"); } TreeNode pNode = node; while(pNode.leftChild!=null){ pNode=pNode.leftChild; } return pNode; } /** * 获取二叉查找树中的最大关键字结点 * @return * @throws Exception */ public TreeNode maxNode(TreeNode node) throws Exception{ if(null==node){ throw new Exception("null tree"); } TreeNode pNode = node; while(pNode.rightChild!=null){ pNode = pNode.rightChild; } return pNode; } /** * 将给定关键字插入到二叉查找树中 * @param key */ public void insert(int key){ TreeNode parentNode = null; TreeNode newNode = new TreeNode(key, null, null, null); TreeNode pNode = root; if(root==null){ root = newNode; return; } while(pNode!=null){ parentNode = pNode; if(key>pNode.key){ pNode = pNode.rightChild; }else if(key<pNode.key){ pNode = pNode.leftChild; }else{ return;//设定不能插入相同的数字 } } if(key<parentNode.key){ parentNode.leftChild = newNode; newNode.parent = parentNode; }else{ parentNode.rightChild = newNode; newNode.parent = parentNode; } } /** * successor: 获取给定结点在中序遍历顺序下的后继结点 * * @param node * 给定树中的结点 * @return 若该结点存在中序遍历顺序下的后继结点,则返回其后继结点;否则返回 null * 分为三种情况: 1.一个节点有右孩子,则在中序遍历中,该节点的后继是它的右子树的最左节点。 2. 这个节点是它父亲的左孩子,则该节点的后继节点是它的父亲 3. 这个节点是它父亲的右孩子,则需要一直向上搜索,直到它们n-1代祖先是它第n代祖先的左孩子, 则它的后继就是第n个祖先。如果一直搜索到根节点,也没有找到n-1代祖先是它第n代祖先的左孩子, 则该节点是整个树的中序遍历中的最后一个节点,即它没有后继。 * @throws Exception */ public TreeNode successor(TreeNode node) throws Exception { if (node == null) { return null; } // 若该结点的右子树不为空,则其后继结点就是右子树中的最小关键字结点 if (node.rightChild != null) { return minNode(node.rightChild); } // 若该结点右子树为空 TreeNode parentNode = node.parent; while (parentNode != null && node == parentNode.rightChild) { node = parentNode; parentNode = parentNode.parent; } return parentNode; } /** * precessor: 获取给定结点在中序遍历顺序下的前趋结点 * * @param node * 给定树中的结点 * @return 若该结点存在中序遍历顺序下的前趋结点,则返回其前趋结点;否则返回 null * @throws Exception */ public TreeNode precessor(TreeNode node) throws Exception { if (node == null) { return null; } // 若该结点的左子树不为空,则其前趋结点就是左子树中的最大关键字结点 if (node.leftChild != null) { return maxNode(node.leftChild); } // 若该结点左子树为空 TreeNode parentNode = node.parent; while (parentNode != null && node == parentNode.leftChild) { node = parentNode; parentNode = parentNode.parent; } return parentNode; } /** * 删除节点 * @param key * @throws Exception */ public void delete(int key) throws Exception{ TreeNode node = search(key); if(node==null){ throw new Exception("不存在"); } delete(node); } private void delete(TreeNode node) throws Exception { if(node==null){ return; } //既没有左侧节点,又没有右侧节点 if(node.leftChild==null&&node.rightChild==null){ TreeNode parentNode = node.parent; if(parentNode.leftChild==node){ parentNode.leftChild=null; }else{ parentNode.rightChild=null; } return; } //没有左侧节点,有右侧节点 if(node.leftChild==null&&node.rightChild!=null){ TreeNode parentNode = node.parent; if(parentNode.leftChild==node){ parentNode.leftChild=node.rightChild; node.rightChild.parent=parentNode; }else{ parentNode.rightChild=node.rightChild; node.rightChild.parent=parentNode; } return; } //有左侧节点,没有右侧节点 if(node.leftChild!=null&&node.rightChild==null){ TreeNode parentNode = node.parent; if(parentNode.leftChild==node){ parentNode.leftChild=node.leftChild; node.leftChild.parent=parentNode; }else{ parentNode.rightChild=node.leftChild; node.leftChild.parent=parentNode; } return; } //左右节点都有 TreeNode successorNode = successor(node); delete(successorNode); node.key = successorNode.key; } /** * 二叉查找树的中序遍历结点列表 * @return */ public List<TreeNode> inOrderTraverseList(){ if(list!=null){ list.clear(); } inOrderTraverse(root); return list; } // 二叉查找树的中序遍历结点列表 private void inOrderTraverse(TreeNode root) { if(root!=null){ inOrderTraverse(root.leftChild); list.add(root); inOrderTraverse(root.rightChild); } } /** * 获取二叉查找树中关键字的有序列表 * * @return 二叉查找树中关键字的有序列表 */ public String toStringOfOrderList() { StringBuilder sbBuilder = new StringBuilder(" [ "); for (TreeNode p : inOrderTraverseList()) { sbBuilder.append(p.key); sbBuilder.append(" "); } sbBuilder.append("]"); return sbBuilder.toString(); } /** * 获取该二叉查找树的字符串表示 */ public String toString() { StringBuilder sbBuilder = new StringBuilder(" [ "); for (TreeNode p : inOrderTraverseList()) { sbBuilder.append(p); sbBuilder.append(" "); } sbBuilder.append("]"); return sbBuilder.toString(); } public TreeNode getRoot() { return root; } }
上面还提到中序遍历
中序遍历(LDR)是二叉树遍历的一种,也叫做中根遍历、中序周游,可记做左根右
中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。在遍历左、右子树时,
仍然先遍历左子树,再访问根结点,最后遍历右子树
前序遍历:根节点->左子树->右子树
中序遍历:左子树->根节点->右子树
后序遍历:左子树->右子树->根节点
层次遍历:第一层->第二层->...eg:12345678
package test4; public class test { public static void main(String[] args) { try { BinarySearchTree bst = new BinarySearchTree(); System.out.println("查找树是否为空? " + (bst.isEmpty() ? "是" : "否")); int[] keys = new int[] { 15, 6, 18, 3, 7, 13, 20, 2, 9, 4 }; for (int key : keys) { bst.insert(key); } System.out.println("查找树是否为空? " + (bst.isEmpty() ? "是" : "否")); TreeNode minkeyNode = bst.minNode(bst.getRoot()); System.out.println("最小关键字: " + minkeyNode.getKey()); testNode(bst, minkeyNode); TreeNode maxKeyNode = bst.maxNode(bst.getRoot()); System.out.println("最大关键字: " + maxKeyNode.getKey()); testNode(bst, maxKeyNode); System.out.println("根结点关键字: " + bst.getRoot().getKey()); testNode(bst, bst.getRoot()); testTraverse(bst); System.out.println("****************************** "); testTraverse(bst); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } } public static void testNode(BinarySearchTree bst, TreeNode pNode) throws Exception { System.out.println("本结点: " + pNode); System.out.println("前趋结点: " + bst.precessor(pNode)); System.out.println("后继结点: " + bst.successor(pNode)); } public static void testTraverse(BinarySearchTree bst) { System.out.println("二叉树遍历:" + bst); System.out.println("二叉查找树转换为有序列表: " + bst.toStringOfOrderList()); } }
package test5; /** * 树节点 */ public class TreeNode { Object key; Object value; TreeNode left; TreeNode right; TreeNode(Object key, Object value, TreeNode left, TreeNode right) { this.key = key; this.value = value; this.left = left; this.right = right; } TreeNode(Object key, Object value) { this(key, value, null, null); } public String toString() { return "[" + key + ":" + value + "]"; } }
package test5; import java.util.Comparator; import java.util.LinkedList; import java.util.Queue; public class BinarySearchTree { TreeNode root; private Comparator<Object> cmp; public BinarySearchTree(Comparator<Object> cmp) { this.cmp = cmp; } public String toString() { return inOrderString(); } public String inOrderString() { StringBuilder sb = new StringBuilder(); _inOrder(sb, root); return sb.toString(); } /** * 中序遍历 */ private void _inOrder(StringBuilder sb, TreeNode n) { if (n.left != null) _inOrder(sb, n.left); sb.append(n + " "); if (n.right != null) _inOrder(sb, n.right); } /** * 层次遍历 * @return */ public String levelOrderString() { if (root == null) return ""; StringBuilder sb = new StringBuilder(); Queue<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root); TreeNode node; while ((node = (TreeNode)queue.poll()) != null) { sb.append(node + " "); if (node.left != null) queue.add(node.left); if (node.right != null) queue.add(node.right); } return sb.toString(); } public TreeNode max() { if (root == null) return null; TreeNode n = root; while (n.right != null) n = n.right; return n; } public TreeNode min() { if (root == null) return null; TreeNode n = root; while (n.left != null) n = n.left; return n; } public boolean insert(TreeNode node) { if (root == null) { root = node; return true; } TreeNode n = root; TreeNode parent = n; boolean isLeft = false; while (n != null) { int result = cmp.compare(node.key, n.key); if (result == 0) return false; else if (result > 0) { parent = n; n = n.right; isLeft = false; } else { parent = n; n = n.left; isLeft = true; } } if (isLeft) parent.left = node; else parent.right = node; return true; } public TreeNode find(Object key) { TreeNode n = root; while (n != null) { int result = cmp.compare(key, n.key); if (result == 0) return n; else if (result > 0) n = n.right; else n = n.left; } return n; } public boolean remove(Object key) { if (root == null) return false; TreeNode n = root; TreeNode parent = n; boolean isLeft = false; while (n != null) { int result = cmp.compare(key, n.key); if (result == 0) { _delete(parent, n, isLeft); return true; } else if (result > 0) { isLeft = false; parent = n; n = n.right; } else { isLeft = true; parent = n; n = n.left; } } return false; } private void _delete(TreeNode parent, TreeNode node, boolean isLeft) { if (node.left == null && node.right == null) { //叶子节点 if (node == root) root = null; else if (isLeft) parent.left = null; else parent.right = null; } else if (node.left == null) { //仅有右子树 if (node == root) root = node.right; else if (isLeft) parent.left = node.right; else parent.right = node.right; } else if (node.right == null) { //仅有左子树 if (node == root) root = node.left; else if (isLeft) parent.left = node.left; else parent.right = node.left; } else { //左右子树均存在 //找到右子树最小节点n TreeNode n = node.right; TreeNode np = node; while (n.left != null) { np = n; n = n.left; } //将n的key和value赋给node node.key = n.key; node.value = n.value; //删除n _delete(np, n, true); } } }
package test5; import java.util.Comparator; import java.util.Random; public class test { public static void main(String[] args) { Random rand = new Random(); BinarySearchTree bst = new BinarySearchTree(new Comparator<Object>() { @Override public int compare(Object o1, Object o2) { if (!(o1 instanceof Integer) || ! (o2 instanceof Integer)) throw new RuntimeException("compare()参数非整型"); return ((Integer)o1).compareTo((Integer)o2); } }); bst.insert(new TreeNode(0, 0)); bst.insert(new TreeNode(50, 50)); bst.insert(new TreeNode(100, 100)); for (int i = 0; i < 10; i++) { bst.insert(new TreeNode(rand.nextInt(100), rand.nextInt(100))); } System.out.println(bst); System.out.println(bst.levelOrderString()); System.out.println(bst.min() + " <<< " + bst.max()); System.out.println(bst.find(0) + " " + bst.find(50) + " " + bst.find(100)); bst.remove(0); bst.remove(50); bst.remove(100); System.out.println(bst); } }
标签:
原文地址:http://www.cnblogs.com/itliucheng/p/5485854.html