用 Java 实现二叉树代码

数据结构中,关于树之一部分的讲解在之前的一篇博客中:数据结构——树
这里就用 Java 实现了一下二叉树的基本算法。



二叉树的结点定义

/**
 * 定义树的节点
 * 即定义二叉链表的节点
 */
public class Node {
    
    
    Object value;
    Node leftChild;
    Node rightChild;

    public Node(Object value){
    
    
        this.value = value;
    }

    public Node(Object value, Node leftChild, Node rightChild){
    
    
        this.value = value;
        this.leftChild = leftChild;
        this.rightChild = rightChild;
    }

    @Override
    public String toString() {
    
    
        return "Node{" +
                "value=" + value +
                ", leftChild=" + leftChild +
                ", rightChild=" + rightChild +
                '}';
    }
}

二叉树的基本算法

主要包括如下算法:

  • 判断二叉树是否为空;
  • 统计二叉树节点个数;
  • 计算二叉树高度;
  • 查找二叉树中的某个值;
  • 先序遍历(递归);
  • 中序遍历(递归);
  • 后序遍历(递归);
  • 层次遍历;
  • 先序遍历(非递归);
  • 中序遍历(非递归);
  • 后序遍历(非递归);
/**
 * 二叉树基本算法
 */
public class LinkedBinaryTree {
    
    

    //判断二叉树是否为空
    public static boolean isEmpty(Node root) {
    
    
        if (root == null){
    
    
            return true;
        }else {
    
    
            return false;
        }
    }

    //输出二叉树节点数量
    //递归思想,节点数 = 左子树 + 右子树 + 1;
    public static int size(Node root) {
    
    
        if (root == null){
    
    
            return 0;
        }else{
    
    
            int sizel = size(root.leftChild);
            int sizer = size(root.rightChild);
            return sizel+sizer+1;
        }
    }

    //二叉树高度
    //递归思想,高度 = 左右子树最大高度 + 1;
    public static int getHeight(Node root) {
    
    
        if (root == null){
    
    
            return 0;
        }else {
    
    
            int heightl = getHeight(root.leftChild);
            int heightr = getHeight(root.rightChild);
            if (heightl > heightr){
    
    
                return heightl + 1;
            }else {
    
    
                return heightr + 1;
            }
        }
    }

    //在二叉树中查找某个值
    //递归思想,将value逐个和 根节点、以及根节点的左右子树值进行比较
    public static Node findKey(Node root, Object value) {
    
    
        if (root == null){
    
    
            return null;
        }else if (root != null && root.value == value){
    
    
            return root;
        }else {
    
    
            Node leftnode = findKey(root.leftChild, value);
            Node rightnode = findKey(root.rightChild, value);
            if (leftnode != null && leftnode.value == value){
    
    
                return leftnode;
            }else if (rightnode != null && rightnode.value == value){
    
    
                return rightnode;
            }else {
    
    
                return null;
            }
        }
    }

    //先序遍历递归
    public static void preOrderTraverse(Node root) {
    
    
        if (root != null){
    
    
            System.out.print(root.value + " ");
            preOrderTraverse(root.leftChild);
            preOrderTraverse(root.rightChild);
        }

    }

    //中序遍历递归
    public static void inOrderTraverse(Node root) {
    
    
        if (root != null){
    
    
            inOrderTraverse(root.leftChild);
            System.out.print(root.value + " ");
            inOrderTraverse(root.rightChild);
        }
    }

    //后序遍历递归
    public static void postOrderTraverse(Node root) {
    
    
        if (root != null){
    
    
            postOrderTraverse(root.leftChild);
            postOrderTraverse(root.rightChild);
            System.out.print(root.value + " ");
        }
    }

    //层次遍历(借助队列)
    //按照从上到下,从左到右遍历;又叫广度优先遍历;
    //可以用 queue队列接口 来完成;LinkedList 实现了该接口;
    public static void levelOrderByStack(Node root) {
    
    
        if (root == null){
    
    
            return;
        }else {
    
    
            Queue<Node> queue = new LinkedList<Node>();
            queue.add(root);
            while (queue.size() != 0){
    
    
                for (int i = 0; i < queue.size(); i++){
    
    
                    Node temp = queue.poll();
                    System.out.print(temp.value + " ");
                    if (temp.leftChild != null){
    
    
                        queue.add(temp.leftChild);
                    }
                    if (temp.rightChild != null){
    
    
                        queue.add(temp.rightChild);
                    }
                }
            }
        }
    }

    //先序遍历 非递归(借助栈)
    public static void preOrderByStack(Node root){
    
    
        Deque<Node> stack = new LinkedList<Node>();
        while (root != null || !stack.isEmpty()){
    
    
            while (root != null){
    
    
                System.out.print(root.value + " ");
                stack.push(root);
                root = root.leftChild;
            }
            if (!stack.isEmpty()){
    
    
                root = stack.pop();
                root = root.rightChild;
            }
        }
    }

    //中序遍历 非递归(借助栈)
    //(1)若根不为空,根入栈,并判断左子树是否为空;
    //(2)若不为空,子树根节点入栈,继续向下,直至左子树为空;
    //(3)若栈中有节点,将其取出,并对其右子树根节点进行1,2两步骤,直至无节点或栈空;
    public static void inOrderByStack(Node root) {
    
    
        Deque<Node> stack = new LinkedList<Node>();
        while (root != null || !stack.isEmpty()){
    
    
            while (root != null){
    
    
                stack.push(root);
                root = root.leftChild;
            }
            if (!stack.isEmpty()){
    
    
                root = stack.pop();
                System.out.print(root.value + " ");
                root = root.rightChild;
            }
        }
    }

    //后序遍历 非递归(借助栈)
    public static void postOrderByStack(Node root){
    
    
        Deque<Node> stack = new LinkedList<Node>();
        Node temp = null;
        while (root != null || !stack.isEmpty()){
    
    
            while (root != null){
    
    
                stack.push(root);
                root = root.leftChild;
            }
            if (!stack.isEmpty()){
    
    
                root = stack.peek();
                if ((root.rightChild == null) || (root.rightChild == temp)){
    
    
                    root = stack.pop();
                    System.out.print(root.value + " ");
                    temp = root;
                    root = null;
                }else {
    
    
                    root = root.rightChild;
                }
            }
        }
    }

    public static void main(String[] args) {
    
    
        //创建二叉树
        Node node_F = new Node("F", null, null);
        Node node_E = new Node("E", null, null);
        Node node_D = new Node("D", null, null);
        Node node_C = new Node("C", node_F, null);
        Node node_B = new Node("B", node_D, node_E);
        Node node_A = new Node("A", node_B, node_C);

        //确定二叉树的根节点
        Node root = node_A;

        //调用函数
        int size = size(root);
        System.out.println("节点个数:" + size);
        int height = getHeight(root);
        System.out.println("树的高度:" + height);
        Node n = findKey(root, "B");
        System.out.println("节点信息:" + n);

        System.out.println("\n先序遍历:");
        preOrderTraverse(root);
        System.out.println("\n中序遍历:");
        inOrderTraverse(root);
        System.out.println("\n后序遍历:");
        postOrderTraverse(root);
        System.out.println("\n层次遍历:");
        levelOrderByStack(root);
        System.out.println("\n先序遍历(非递归)");
        preOrderByStack(root);
        System.out.println("\n中序遍历(非递归):");
        inOrderByStack(root);
        System.out.println("\n后续遍历(非递归):");
        postOrderByStack(root);
    }
}

猜你喜欢

转载自blog.csdn.net/pary__for/article/details/110237645