Java实现二叉搜索树: 非递归实现前序、中序、后序、层次遍历

package com.ustb.datastruct.ch8.tree;

import java.util.*;

/**
 * This is a class about Tree DataStruct
 *
 * @author re-get
 * @since 1.0.0
 */
public class Tree<K, V> {
    private Node<K, V> root;
    private final Comparator<? super K> comparator;
    private static final int MAX_BLANKS = 32;
    private static final int BLANKS_TIMES = 2;
    private static final int APPEND_BLANKS = 2;

    public Tree(Comparator<? super K> comparator) {
        this.comparator = comparator;
        root = null;
    }

    /**
     * This is a class about the basic node of tree
     *
     * @author re-get
     * @since 1.0.0
     */
    static final class Node<K, V> {
        private K key;
        private V value;
        private Node<K, V> leftChild;
        private Node<K, V> rightChild;

        public Node(K key, V value) {
            this.key = key;
            this.value = value;
            this.leftChild = null;
            this.rightChild = null;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append('{').append(key.toString()).append(',').append(value.toString()).append('}');
            return sb.toString();
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            Node<?, ?> node = (Node<?, ?>) o;
            return Objects.equals(key, node.key) &&
                    Objects.equals(value, node.value) &&
                    Objects.equals(leftChild, node.leftChild) &&
                    Objects.equals(rightChild, node.rightChild);
        }

        @Override
        public int hashCode() {
            return Objects.hash(key, value);
        }

    }

    /**
     * This function to find a node which key is key
     *
     * @return the node to find by key
     */
    public Node<K, V> find(K key) {
        Node<K, V> current = root;
        while (current != null) {
            if (current.key == key) {
                return current;
            } else if (this.comparator.compare(current.key, key) > 0) {
                current = current.leftChild;
            } else {
                current = current.rightChild;
            }
        }
        return null;
    }

    /**
     * This function to insert a node into tree
     * If the key is already exist in the ree it will overwrite the node
     */
    public void insert(K key, V value) {
        Node<K, V> iNode = new Node<>(key, value);
        if (root == null) {
            root = iNode;
        } else {
            Node<K, V> current = root;
            while (true) {
                if (this.comparator.compare(current.key, key) == 0) {
                    current.value = value;
                    return;
                } else if (this.comparator.compare(current.key, key) > 0) {
                    if (current.leftChild == null) {
                        current.leftChild = iNode;
                        return;
                    } else {
                        current = current.leftChild;
                    }
                } else {
                    if (current.rightChild == null) {
                        current.rightChild = iNode;
                        return;
                    } else {
                        current = current.rightChild;
                    }
                }
            }
        }
    }

    /**
     * @param key key is the key word to delete node
     * @return if the node is delete
     */
    public boolean delete(K key) {
        if (root == null) {
            return false;
        } else {
            Node<K, V> current = root;
            Node<K, V> currentParent = null;
            boolean isLeftChild = true;
            while (true) {
                if (current == null) {
                    return false;
                } else if (this.comparator.compare(current.key, key) == 0) {
                    break;
                } else if (this.comparator.compare(current.key, key) > 0) {
                    currentParent = current;
                    current = current.leftChild;
                    isLeftChild = true;
                } else {
                    currentParent = current;
                    current = current.rightChild;
                    isLeftChild = false;
                }
            }
            // 分情况讨论
            if (current.leftChild == null
                    && current.rightChild == null) {
                // 1:子节点均为null
                if (currentParent == null) {
                    root = null;
                } else {
                    if (isLeftChild) {
                        currentParent.leftChild = null;
                    } else {
                        currentParent.rightChild = null;
                    }
                }
            } else if (current.leftChild == null) {
                // 2:左节点为null
                if (currentParent == null) {
                    root = root.rightChild;
                } else {
                    if (isLeftChild) {
                        currentParent.leftChild = current.rightChild;
                    } else {
                        currentParent.rightChild = current.rightChild;
                    }
                }
            } else if (current.rightChild == null) {
                // 3:右节点为null
                if (currentParent == null) {
                    root = root.leftChild;
                } else {
                    if (isLeftChild) {
                        currentParent.leftChild = current.leftChild;
                    } else {
                        currentParent.rightChild = current.leftChild;
                    }
                }
            } else {
                // 4:左右节点均不为空
                Node<K, V> successor = getSuccessor(current);
                successor.leftChild = current.leftChild;
                if (currentParent == null) {
                    root = successor;
                } else if (isLeftChild) {
                    currentParent.leftChild = successor;
                } else {
                    currentParent.rightChild = successor;
                }
            }
            return true;
        }
    }

    public List<Node<K, V>> preOrder() {
        return preOrder(root);
    }

    public List<Node<K, V>> preOrder(Node<K, V> node) {
        List<Node<K, V>> preList = new ArrayList<>();
        Stack<Node<K, V>> stack = new Stack<>();
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                preList.add(node);
                stack.push(node);
                node = node.leftChild;
            }
            if (!stack.isEmpty()) {
                node = stack.pop();
                node = node.rightChild;
            }
        }
        return preList;
    }

    public List<Node<K, V>> inOrder() {
        return inOrder(root);
    }

    public List<Node<K, V>> inOrder(Node<K, V> node) {
        List<Node<K, V>> inList = new ArrayList<>();
        Stack<Node<K, V>> stack = new Stack<>();
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                stack.add(node);
                node = node.leftChild;
            }
            if (!stack.isEmpty()) {
                node = stack.pop();
                inList.add(node);
                node = node.rightChild;
            }
        }
        return inList;
    }

    public List<Node<K, V>> postOrder() {
        return postOrder(root);
    }

    public List<Node<K, V>> postOrder(Node<K, V> node) {
        List<Node<K, V>> postList = new ArrayList<>();
        Stack<Node<K, V>> stack = new Stack<>();
        // 使用额外的栈存储其是否为右子树
        Stack<Boolean> flagStack = new Stack<>();
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                stack.push(node);
                flagStack.push(false);
                node = node.leftChild;
            }
            while (!stack.isEmpty() && flagStack.peek()) {
                postList.add(stack.pop());
                flagStack.pop();
            }
            if (!stack.isEmpty()) {
                flagStack.pop();
                flagStack.push(true);
                node = stack.peek().rightChild;
            }
        }
        return postList;
    }

    public List<Node<K, V>> layerOrder() {
        List<Node<K, V>> layerList = new ArrayList<>();
        Queue<Node<K, V>> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            for (int i = 0, n = queue.size(); i < n; i++) {
                Node<K, V> temp = queue.poll();
                layerList.add(temp);
                assert temp != null;
                Node<K, V> leftChild = temp.leftChild;
                Node<K, V> rightChild = temp.rightChild;
                if (leftChild != null) {
                    queue.offer(leftChild);
                }
                if (rightChild != null) {
                    queue.offer(rightChild);
                }
            }
        }
        return layerList;
    }

    private Node<K, V> getSuccessor(Node<K, V> delNode) {
        Node<K, V> currentParent = delNode;
        Node<K, V> current = currentParent.rightChild;
        while (current.leftChild != null) {
            currentParent = current;
            current = current.leftChild;
        }
        if (current != delNode.rightChild) {
            currentParent.leftChild = current.rightChild;
            current.rightChild = delNode.rightChild;
        }
        return current;
    }

    public void displayTree() {
        int nBlanks = MAX_BLANKS;
        boolean isRowEmpty = false;
        Queue<Node<K, V>> queue = new LinkedList<>();
        queue.offer(root);
        for (int i = 0; i < MAX_BLANKS * BLANKS_TIMES + APPEND_BLANKS; i++) {
            System.out.print('*');
        }
        System.out.println();
        while (!isRowEmpty) {
            isRowEmpty = true;
            for (int j = 0; j < nBlanks; j++) {
                System.out.print(' ');
            }
            for (int i = 0, n = queue.size(); i < n; i++) {
                Node<K, V> temp = queue.poll();
                if (temp == null) {
                    System.out.print("--");
                    queue.offer(null);
                    queue.offer(null);
                } else {
                    isRowEmpty = false;
                    System.out.print(temp.key);
                    queue.offer(temp.leftChild);
                    queue.offer(temp.rightChild);
                }
                for (int j = 0; j < nBlanks * BLANKS_TIMES - APPEND_BLANKS; j++) {
                    System.out.print(' ');
                }
            }
            System.out.println();
            nBlanks /= 2;
            for (int i = 0; i < MAX_BLANKS * BLANKS_TIMES + APPEND_BLANKS; i++) {
                System.out.print('-');
            }
            System.out.println();
        }
    }
}
posted @ 2020-04-23 17:13  re_get  阅读(171)  评论(0)    收藏  举报