package com.aaront.exercise.generic; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Stack; public class GenericBinaryTree<T extends Comparable<T>> { private BinaryTreeNode<T> head = new BinaryTreeNode<>(null); private BinaryTreeNode<T> root; private int size; private int index = 0; public static final int PREORDER = 0; public static final int INORDER = 1; public static final int POSTORDER = 2; public static final int HIERARCHICAL = 3; public static final int RECURSION = 10; public static final int ITERATION = 11; public void add(T o) { BinaryTreeNode<T> node = new BinaryTreeNode<>(o); if (root == null) { root = node; head.setLeft(root); } else { insert(root, node); } size++; } private void insert(BinaryTreeNode<T> node, BinaryTreeNode<T> newNode) { // 要插入的节点插入当前节点的左子树 if (node.getData().compareTo(newNode.getData()) > 0) { if (node.getLeft() == null) { node.setLeft(newNode); } else { insert(node.left, newNode); } } else { // 要插入的节点插入当前节点的右子树 if (node.getRight() == null) { node.setRight(newNode); } else { insert(node.right, newNode); } } } public BinaryTreeNode<T> search(T data) { return search(data, ITERATION); } public BinaryTreeNode<T> search(T data, int method) { switch (method) { case RECURSION: return findNodeRecursion(root, data); case ITERATION: return findNodeIteration(data); default: throw new IllegalArgumentException("不支持的查找方法"); } } private BinaryTreeNode<T> findNodeRecursion(BinaryTreeNode<T> node, T data) { if (node == null) return null; if (node.getData().compareTo(data) == 0) return node; if (node.getData().compareTo(data) > 0) return findNodeRecursion(node.getLeft(), data); return findNodeRecursion(node.getRight(), data); } private BinaryTreeNode<T> findNodeIteration(T data) { BinaryTreeNode<T> currentNode = root; while (currentNode != null) { if (currentNode.getData().compareTo(data) == 0) { return currentNode; } if (currentNode.getData().compareTo(data) > 0) { currentNode = currentNode.getLeft(); } else { currentNode = currentNode.getRight(); } } return null; } public BinaryTreeNode<T> min() { return findMin(root); } private BinaryTreeNode<T> findMin(BinaryTreeNode<T> node) { if (node == null) return null; if (node.getLeft() == null) return node; return findMin(node.getLeft()); } public BinaryTreeNode<T> max() { return findMax(root); } private BinaryTreeNode<T> findMax(BinaryTreeNode<T> node) { if (node == null) return null; if (node.getRight() == null) return node; return findMax(node.getRight()); } public void delete(T data) { BinaryTreeNode<T> node = search(data); if (node == null) return; BinaryTreeNode<T> parentNode = searchParentNode(node); if (parentNode == null) return; // 删除叶子节点 if (node.getLeft() == null && node.getRight() == null) { if (parentNode.getLeft() == node) parentNode.setLeft(null); else parentNode.setRight(null); } else if (node.getLeft() != null && node.getRight() == null) { // 删除只有左子树的节点 if (parentNode.getLeft() == node) parentNode.setLeft(node.getLeft()); else parentNode.setRight(node.getLeft()); } else if (node.getRight() != null && node.getLeft() == null) { // 删除只有右子树的节点 if (parentNode.getLeft() == node) parentNode.setLeft(node.getRight()); else parentNode.setRight(node.getRight()); } else { // 删除有两个子树的节点 BinaryTreeNode<T> replace = findMin(node.getRight()); BinaryTreeNode<T> replaceParentNode = searchParentNode(replace); replaceParentNode.setLeft(replace.getRight()); node.setData(replace.getData()); replace.setLeft(null); replace.setRight(null); } size--; } private BinaryTreeNode<T> searchParentNode(BinaryTreeNode<T> node) { if (node == null) return null; if (node == root) return head; BinaryTreeNode<T> current = root; while (current != null) { if (current.getLeft() == node || current.getRight() == node) return current; if (current.getData().compareTo(node.getData()) > 0) current = current.getLeft(); else current = current.getRight(); } return null; } public Object[] traversal() { return traversal(PREORDER); } public T[] traversal(T[] a) { Object[] elementData = traversal(PREORDER); return toArray(elementData, a); } public T[] traversal(int order, T[] a) { Object[] elementData = traversal(order); return toArray(elementData, a); } private T[] toArray(Object[] elementData, T[] a) { if (a.length < size) // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); return a; } public Object[] traversal(int order) { Object[] datas = new Object[size]; if (order == PREORDER) { preorderTraversal(root, datas); } else if (order == INORDER) { inorderTraversal(root, datas); } else if (order == POSTORDER) { postorderTraversal(root, datas); } else { hierarchicalTraversal(root, datas); } index = 0; return datas; } public List<T> traversalWithoutRecursion(int order) { if (order == PREORDER) { return preorderWithoutRecursion(root); } else if (order == INORDER) { return inorderWithoutRecursion(root); } else if (order == POSTORDER) { return postorderWithoutRecursion(root); } else { return hierarchicalTraversalWithoutRecursion(root); } } private List<T> preorderWithoutRecursion(BinaryTreeNode<T> root) { List<T> nodes = new ArrayList<>(); Stack<BinaryTreeNode<T>> stack = new Stack<>(); while (root != null) { nodes.add(root.getData()); if (root.getRight() != null) { stack.push(root.getRight()); } if (root.getLeft() != null) { root = root.getLeft(); } else { if (stack.isEmpty()) break; root = stack.pop(); } } return nodes; } private List<T> inorderWithoutRecursion(BinaryTreeNode<T> root) { List<T> nodes = new ArrayList<>(); Stack<BinaryTreeNode<T>> stack = new Stack<>(); while (root != null || !stack.isEmpty()) { while (root != null) { stack.push(root); root = root.getLeft(); } BinaryTreeNode<T> node = stack.pop(); nodes.add(node.getData()); root = node.getRight(); } return nodes; } private List<T> postorderWithoutRecursion(BinaryTreeNode<T> root) { List<T> nodes = new ArrayList<>(); Stack<BinaryTreeNode<T>> stack = new Stack<>(); stack.push(root); BinaryTreeNode<T> pre = null; BinaryTreeNode<T> cur = null; while (!stack.isEmpty()) { cur = stack.peek(); // 如果当前节点是叶子节点 || 当前节点的左右节点都已经被访问过了, 则可以直接访问当前节点 if (cur.getLeft() == null && cur.getRight() == null || pre != null && (cur.getLeft() == pre || cur.getRight() == pre)) { nodes.add(cur.getData()); stack.pop(); pre = cur; } else { if (cur.getRight() != null) stack.push(cur.getRight()); if (cur.getLeft() != null) stack.push(cur.getLeft()); } } return nodes; } private List<T> hierarchicalTraversalWithoutRecursion(BinaryTreeNode<T> root) { return new ArrayList<>(); } private void preorderTraversal(BinaryTreeNode<T> node, Object[] datas) { if (node == null) { return; } datas[index++] = node.getData(); preorderTraversal(node.getLeft(), datas); preorderTraversal(node.getRight(), datas); } private void inorderTraversal(BinaryTreeNode<T> node, Object[] datas) { if (node == null) { return; } inorderTraversal(node.getLeft(), datas); datas[index++] = node.getData(); inorderTraversal(node.getRight(), datas); } private void postorderTraversal(BinaryTreeNode<T> node, Object[] datas) { if (node == null) { return; } postorderTraversal(node.getLeft(), datas); postorderTraversal(node.getRight(), datas); datas[index++] = node.getData(); } private void hierarchicalTraversal(BinaryTreeNode<T> node, Object[] datas) { if (node == null) return; GenericQueue<BinaryTreeNode<T>> queue = new GenericQueue<>(); queue.enQueue(node); while (!queue.isEmpty()) { BinaryTreeNode<T> tmp = queue.deQueue(); datas[index++] = tmp.getData(); if (tmp.getLeft() != null) queue.enQueue(tmp.getLeft()); if (tmp.getRight() != null) queue.enQueue(tmp.getRight()); } } class BinaryTreeNode<T extends Comparable<T>> { private T data; private BinaryTreeNode<T> left; private BinaryTreeNode<T> right; public BinaryTreeNode(T data) { this.data = data; } public T getData() { return data; } public void setData(T data) { this.data = data; } public BinaryTreeNode<T> getLeft() { return left; } public void setLeft(BinaryTreeNode<T> left) { this.left = left; } public BinaryTreeNode<T> getRight() { return right; } public void setRight(BinaryTreeNode<T> right) { this.right = right; } } }