标签:tty order mil ash imu 速度 时间复杂度 round 微软
/*** 节点类** @author Frank**/public class TreeNode {int keyData;// 关键值(可能还有别的非关键数据,这里省略)TreeNode leftChild;// 左子节点TreeNode rightChild;// 右子节点public TreeNode(int keyData) {super();this.keyData = keyData;}/*** 显示该节点信息*/public void display() {System.out.println("TreeNode [keyData=" + keyData + ", leftChild=" + leftChild + ", rightChild=" + rightChild + "]");}@Overridepublic String toString() {return "TreeNode [keyData=" + keyData + "]";}}
import java.util.HashMap;import java.util.Iterator;import java.util.Set;/*** 二叉查找树** @author Frank**/public class Tree {TreeNode root;// 根节点private TreeNode parent;// 父节点public Tree(TreeNode root) {super();this.root = root;}/*** 以关键值查找节点是否存在** @param keyData* 节点关键值* @return 若该树包含关键值对应的 Node,返回 true*/public boolean findNode(int keyData) {TreeNode current = root;// 当前节点while (current != null) {if (current.keyData == keyData)return true;// 找到了if (current.keyData > keyData) // 往左遍历current = current.leftChild;if (current.keyData < keyData) // 往右遍历current = current.rightChild;}return false;// 未找到}/*** 将节点插入当前树** @param node* 新插入的节点*/public void insert(TreeNode node) {if (!this.isEmpty()) {boolean isLeftChild = true;int keyData = node.keyData;TreeNode current = root;// 当前节点parent = null;while (current != null) {parent = current;if (keyData == current.keyData)return;// 关键值一样则不插入current = (keyData < current.keyData) ? (current.leftChild) : (current.rightChild);isLeftChild = (keyData < parent.keyData) ? true : false;}if (isLeftChild) {parent.leftChild = node;} else {parent.rightChild = node;}}}/*** 将集合中的所有节点插入当前树** @param node* 新插入的节点*/public void insert(Set<TreeNode> nodeSet) {Iterator<TreeNode> iterator = nodeSet.iterator();while (iterator.hasNext()) {insert(iterator.next());}}/*** 判断当前树是否为空** @return 若为空,返回 true*/public boolean isEmpty() {return root == null;}// 通过递归实现中序遍历输出private void getOrder(TreeNode localRoot) {if (localRoot != null) {getOrder(localRoot.leftChild);System.out.print(localRoot.keyData + " ");getOrder(localRoot.rightChild);}}/*** 中序遍历指定的子树,若指定的节点并不是本树的节点(以关键值为标准,可能出现非关键值不一样的正常遍历),则不输出任何值** @param localRoot* 指定节点对象,若为 root 节点则遍历当前树*/public void inOrder(TreeNode localRoot) {if (localRoot != null && findNode(localRoot.keyData)) {TreeNode current = getNode(localRoot.keyData);getOrder(current);System.out.println();}}/*** 获取指定关键值对应的节点,该节点需存在于本树中** @param keyData* 节点关键值* @return 若存在这样的节点则返回此节点,否则返回 null*/public TreeNode getNode(int keyData) {TreeNode current = root;// 当前节点while (current != null) {if (current.keyData == keyData)return current;// 找到了if (current.keyData > keyData) // 往左遍历current = current.leftChild;if (current.keyData < keyData) // 往右遍历current = current.rightChild;}return null;// 未找到}/*** 获取当前树的最小关键值节点** @return 最小关键值对应的节点,若树为空则返回 null*/public TreeNode minimum() {if (!this.isEmpty()) {parent = null;TreeNode minmum = root;while ((minmum = minmum.leftChild) != null) {parent = minmum;}return parent;}return null;}/*** 获取当前树的最大关键值节点** @return 最大关键值对应的节点,若树为空则返回 null*/public TreeNode maximum() {if (!this.isEmpty()) {parent = null;TreeNode maximum = root;while ((maximum = maximum.rightChild) != null) {parent = maximum;}return parent;}return null;}/*** 获取指定节点的子节点个数** @param keyData* 节点关键值* @return 返回拥有 keyData 关键值的节点的子节点个数,若节点不存在与本树,返回-1*/public HashMap<Integer, Boolean> numOfChildren(int keyData) {HashMap<Integer, Boolean> returnMap = new HashMap<Integer, Boolean>();if (this.isEmpty() || !findNode(keyData)) {returnMap.put(-1, false);return returnMap;}TreeNode current = root;parent = null;boolean isLeftChild = true;while (current != null) {if (keyData == current.keyData) {break;}parent = current;current = (keyData < current.keyData) ? (current.leftChild) : (current.rightChild);isLeftChild = (keyData < parent.keyData) ? true : false;}if (current.leftChild == null && current.rightChild == null) {returnMap.put(0, isLeftChild);} else if (current.leftChild != null && current.rightChild != null) {returnMap.put(2, isLeftChild);} else {returnMap.put(1, isLeftChild);}return returnMap;}/*** 删除指定关键值对应的节点,若为非叶子节点,当直接子节点仅有一个时,由该子节点继承,若直接子节点为两个,则由后继节点继承,各子节点保持规律不变,* 即左子节点小于父节点,父节点小于右子节点** @param keyData* 叶子节点的关键值* @return 删除成功返回 true,否则返回 false*/public boolean delete(int keyData) {HashMap<Integer, Boolean> map = numOfChildren(keyData);boolean isLeftChild = map.values().iterator().next();switch (map.keySet().iterator().next()) {case -1:return false;case 0:if (isLeftChild) {parent.leftChild = null;} else {parent.rightChild = null;}return true;case 1:if (isLeftChild) {TreeNode current = parent.leftChild;parent.leftChild = (current.leftChild == null) ? current.rightChild : parent.leftChild.leftChild;} else {TreeNode current = parent.rightChild;parent.rightChild = (current.leftChild == null) ? current.rightChild : parent.leftChild.leftChild;}return true;case 2:TreeNode successorNode = getSuccessor(new TreeNode(keyData));// 该节点的后继节点,即将替换被删除节点TreeNode delNode = null;// 将要删除的节点if (isLeftChild) {// 将要删除的节点是其父节点的左子节点if (parent == null) {// 删除整个树root = null;return true;}delNode = parent.leftChild;if (delNode.rightChild == null) {break;} else if (successorNode.keyData == delNode.rightChild.keyData) {// 后继节点是delNode的右子节点parent.leftChild = successorNode;// 1.将要删除的节点替换为后继节点successorNode.leftChild = delNode.leftChild;// 2.将后继节点的左子节点替换为将要删除的节点的左子节点} else {// 后继节点是delNode的右子节点的左后代TreeNode successorParent = getParent(successorNode);// 获取后继节点的父节点,后继节点一定是这个父节点的左子节点parent = getParent(delNode);successorParent.leftChild = successorNode.rightChild;// 1.将后继节点的父节点的左子节点替换为后继节点的右子节点successorNode.rightChild = delNode.rightChild;// 2.将后继节点的右子节点换为将要删除的节点的右子节点parent.leftChild = successorNode;// 3.将要删除的节点替换为后继节点successorNode.leftChild = delNode.leftChild;// 4.将后继节点的左子节点替换为将要删除的节点的左子节点}} else {// 将要删除的节点是其父节点的右子节点delNode = parent.rightChild;if (successorNode.keyData == delNode.rightChild.keyData) {// 后继节点是delNode的右子节点parent.rightChild = successorNode;// 1.将要删除的节点替换为后继节点successorNode.leftChild = delNode.leftChild;// 2.将后继节点的左子节点替换为将要删除的节点的左子节点} else {// 后继节点是delNode的右子节点的左后代TreeNode successorParent = getParent(successorNode);// 获取后继节点的父节点,后继节点一定是这个父节点的左子节点parent = getParent(delNode);successorParent.leftChild = successorNode.rightChild;// 1.将后继节点的父节点的左子节点替换为后继节点的右子节点successorNode.rightChild = delNode.rightChild;// 2.将后继节点的右子节点换为将要删除的节点的右子节点parent.rightChild = successorNode;// 3.将要删除的节点替换为后继节点successorNode.leftChild = delNode.leftChild;// 4.将后继节点的左子节点替换为将要删除的节点的左子节点}}return true;}return false;}// 获取指定节点的父节点private TreeNode getParent(TreeNode node) {int keyData = node.keyData;if (this.isEmpty() || !findNode(keyData)) {return null;}TreeNode current = root;parent = null;while (current != null) {if (keyData == current.keyData) {break;}parent = current;current = (keyData < current.keyData) ? (current.leftChild) : (current.rightChild);}return parent;}/*** 获取指定节点的后继节点,后继节点应为:在该节点的子节点中,关键值大于该节点关键值且最接近的那个,该方法为删除方法提供支持** @param del* 将要删除的节点* @return*/private TreeNode getSuccessor(TreeNode del) {if (this.isEmpty() || !findNode(del.keyData))return null;int keyData = del.keyData;TreeNode current = root;while (current != null) {if (keyData == current.keyData) {break;}current = (keyData < current.keyData) ? (current.leftChild) : (current.rightChild);}if (current.rightChild == null) {return null;// 无后继节点}TreeNode successorNode = current.rightChild;while (successorNode.leftChild != null) {successorNode = successorNode.leftChild;}return successorNode;}}
标签:tty order mil ash imu 速度 时间复杂度 round 微软
原文地址:http://www.cnblogs.com/chendifan/p/6883660.html