public class SortedBinTree<T extends Comparable> { static class Node { Object data; Node parent; Node left; Node right; public Node(Object data, Node parent, Node left, Node right) { this.data = data; this.parent = parent; this.left = left; this.right = right; } public String toString() { return "[data=" + data + "]"; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj.getClass() == Node.class) { Node target = (Node)obj; return data.equals(target.data) && left == target.left && right == target.right && parent == target.parent; } } } private Node root; public SortedBinTree() { this.root = null; } public SortedBinTree(T o) { this.root = new Node(o, null, null, null); } /** * 新增節點 * (1)以根節點爲當前節點開始搜索 * (2)拿新節點的值和當前節點的值比較 * (3)若是新節點的值更大,則以當前節點的右子節點做爲新的當前節點;不然以當前節點的左子節點做爲新的當前節點。 * (4)重複(2),(3)兩個步驟,直到搜索到合適的葉子節點。 * (5)將新節點添加爲第(4)步找到的葉子節點的子節點,若是新節點更大, * 則添加爲右子節點;不然,加爲左子節點。 */ public void add(T ele) { if (root == null) { root = new Node(ele, null, null, null); } else { Node current = root; Node parent = null; int cmp = 0; do { parent = current; cmp = ele.compareTo(current.data); if (cmp > 0) { current = current.right; } else { current = current.left; } } while (current != null); Node newNode = new Node(ele, parent, null, null); if (cmp > 0) { parent.right = newNode; } else { parent.left = newNode; } } } /** * 刪除節點 * (1)被刪除的節點是葉子節點:只需將它從其父節點中刪除。 * * (2)被刪除節點p(非根節點)只有左子樹:若被刪除節點p是其父節點的右子樹,則讓p的左子樹pL添加成p的父節點的右子樹; * 被刪除節點p是其父節點的左子樹,則讓p的左子樹pL添加成p的父節點的左子樹。 * * (3)被刪除節點p(非根節點)只有右子樹:若被刪除節點p是其父節點的右子樹,則讓p的右子樹pR添加成p的父節點的右子樹; * 被刪除節點p是其父節點的左子樹,則讓p的右子樹pR添加成p的父節點的左子樹。 * * (4)若被刪除節點p的左、右子樹均非空,處理方式有兩種 * a、將pL設爲p的父節點q的左或右子節點(取決於p是其父節點q的左、右子節點),將pR設爲p節點的中序前趨節點s的右子節點 * (s是pL最右下的節點,也就是pL子樹中最大的節點) * b、以p節點的中序前趨或後繼替代p所指節點,而後在從原排序二叉樹中刪去中序前趨或後繼節點。 * (即用大於p的最小節點或小於p的最大節點代替p節點) */ public void remove(T ele) { Node target = getNode(ele); if (target == null) { return; } if (target.left == null && target.right == null) { // 左、右子樹爲空 if (target == root) { root = null; } else { if (target == target.parent.left) { target.parent.left = null; } else { target.parent.right = null; } target.parent = null; } } else if (target.left == null && target.right != null) { // 左子樹爲空,右子樹不爲空 if (target == root) { root = target.right; } else { if (target == target.parent.left) { // 讓target的父節點的left指向target的右子樹 target.parent.left = target.right; } else { // 讓target的父節點的right指向target的右子樹 target.parent.right = target.right; } // 讓target的右子樹的parent指向target的parent target.right.parent = target.parent; } } else if (target.left != null && target.right == null) { // 左子樹不爲空,右子樹爲空 if (target == root) { root = target.left; } else { if (target == target.parent.left) { // 讓target的父節點的left指向target的左子樹 target.parent.left = target.left; } else { // 讓target的父節點的right指向target的左子樹 target.parent.right = target.left; } // 讓target的左子樹的parent指向target的parent target.left.parent = target.parent; } } else if (target.left != null && target.right != null) { // 左、右子樹不爲空 // leftMaxNode用於保存target節點的左子樹中值最大的節點 Node leftMaxNode = target.left; while (leftMaxNode.right != null) { leftMaxNode = leftMaxNode.right; } // 從原來子樹中刪除leftMaxNode節點 leftMaxNode.parent.right = null; // 讓leftMaxNode的parent指向target的parent leftMaxNode.parent = target.parent; if (target == target.parent.left) { // 讓target的父節點的left指向leftMaxNode target.parent.left = leftMaxNode; } else { // 讓target的父節點的right指向leftMaxNode target.parent.right = leftMaxNode; } leftMaxNode.left = target.left; leftMaxNode.right = target.right; target.parent = target.left = target.right = null; } } // 根據給定的值搜索節點 public Node getNode(T ele) { Node p = root; while (p != null) { int cmp = ele.compareTo(p.data); if (cmp < 0) { p = p.left; } else if (cmp > 0) { p = p.right; } else { return p; } } return null; } // 廣度優先遍歷 public List<Node> breadthFirst() { Queue<Node> queue = new ArrayDeque<Node>(); List<Node> list = new ArrayList<Node>(); if (root != null) { // 將根元素加入"隊列" queue.offer(root); } while (!queue.isEmpty()) { list.add(queue.peek()); Node p = queue.poll(); if (p.left != null) { queue.offer(p.left); } if (p.right != null) { queue.offer(p.right); } } return list; } }