返回

二叉树:深入浅出,用Java实现基本操作

后端

什么是二叉树

二叉树是一种由节点和边组成的树形结构。每个节点可以最多有两个子节点,左子节点和右子节点。一个二叉树可以被看作是一棵倒立的树,其中根节点位于顶部,叶子节点位于底部。

二叉树的特点

  • 二叉树是一种非线性数据结构,它不像数组和链表那样具有严格的顺序性。
  • 二叉树是一种层次结构,它可以将数据组织成不同的层次,使得查找和访问数据更加方便。
  • 二叉树是一种递归结构,它可以通过递归的方式来遍历和操作。

二叉树的分类

二叉树可以分为以下几种类型:

  • 满二叉树: 每个节点都有两个子节点的二叉树称为满二叉树。
  • 完全二叉树: 除了最后一层之外,所有层的节点都有两个子节点的二叉树称为完全二叉树。
  • 平衡二叉树: 左右子树的高度差不超过1的二叉树称为平衡二叉树。
  • AVL树: 左右子树的高度差不超过1,并且每个节点的平衡因子在-1到1之间的二叉树称为AVL树。
  • 红黑树: 满足以下条件的二叉树称为红黑树:
    • 每个节点要么是红色,要么是黑色。
    • 根节点是黑色。
    • 每个红色节点的两个子节点都是黑色。
    • 从任何一个节点到其后代所有黑色节点的路径都包含相同数量的黑色节点。

二叉树的遍历

二叉树的遍历是指按照一定的顺序访问二叉树中的所有节点。二叉树的遍历算法有许多种,其中最常见的包括:

  • 前序遍历: 先访问根节点,然后访问左子树,最后访问右子树。
  • 中序遍历: 先访问左子树,然后访问根节点,最后访问右子树。
  • 后序遍历: 先访问左子树,然后访问右子树,最后访问根节点。

二叉树的基本操作

二叉树的基本操作包括:

  • 创建二叉树: 根据给定的数据创建一棵二叉树。
  • 插入节点: 将一个节点插入到二叉树中。
  • 删除节点: 从二叉树中删除一个节点。
  • 查找节点: 在二叉树中查找一个节点。
  • 遍历二叉树: 按照一定的顺序访问二叉树中的所有节点。

用Java实现二叉树的基本操作

在Java中,我们可以使用二叉树类来表示二叉树。二叉树类包含以下几个属性:

  • 根节点: 二叉树的根节点。
  • 左子树: 二叉树的左子树。
  • 右子树: 二叉树的右子树。

二叉树类还包含以下几个方法:

  • 创建二叉树: 根据给定的数据创建一棵二叉树。
  • 插入节点: 将一个节点插入到二叉树中。
  • 删除节点: 从二叉树中删除一个节点。
  • 查找节点: 在二叉树中查找一个节点。
  • 遍历二叉树: 按照一定的顺序访问二叉树中的所有节点。

以下是一个用Java实现的二叉树类:

public class BinaryTree {

    private Node root;

    public BinaryTree() {
        this.root = null;
    }

    public void insert(int data) {
        Node newNode = new Node(data);
        if (root == null) {
            root = newNode;
        } else {
            insertNode(newNode, root);
        }
    }

    private void insertNode(Node newNode, Node current) {
        if (newNode.getData() < current.getData()) {
            if (current.getLeft() == null) {
                current.setLeft(newNode);
            } else {
                insertNode(newNode, current.getLeft());
            }
        } else {
            if (current.getRight() == null) {
                current.setRight(newNode);
            } else {
                insertNode(newNode, current.getRight());
            }
        }
    }

    public Node search(int data) {
        return searchNode(data, root);
    }

    private Node searchNode(int data, Node current) {
        if (current == null) {
            return null;
        }
        if (current.getData() == data) {
            return current;
        }
        if (data < current.getData()) {
            return searchNode(data, current.getLeft());
        } else {
            return searchNode(data, current.getRight());
        }
    }

    public void delete(int data) {
        root = deleteNode(data, root);
    }

    private Node deleteNode(int data, Node current) {
        if (current == null) {
            return null;
        }
        if (data < current.getData()) {
            current.setLeft(deleteNode(data, current.getLeft()));
        } else if (data > current.getData()) {
            current.setRight(deleteNode(data, current.getRight()));
        } else {
            if (current.getLeft() == null) {
                return current.getRight();
            } else if (current.getRight() == null) {
                return current.getLeft();
            } else {
                Node successor = findSuccessor(current.getRight());
                current.setData(successor.getData());
                current.setRight(deleteNode(successor.getData(), current.getRight()));
            }
        }
        return current;
    }

    private Node findSuccessor(Node current) {
        while (current.getLeft() != null) {
            current = current.getLeft();
        }
        return current;
    }

    public void preOrderTraversal() {
        preOrderTraversal(root);
    }

    private void preOrderTraversal(Node current) {
        if (current == null) {
            return;
        }
        System.out.print(current.getData() + " ");
        preOrderTraversal(current.getLeft());
        preOrderTraversal(current.getRight());
    }

    public void inOrderTraversal() {
        inOrderTraversal(root);
    }

    private void inOrderTraversal(Node current) {
        if (current == null) {
            return;
        }
        inOrderTraversal(current.getLeft());
        System.out.print(current.getData() + " ");
        inOrderTraversal(current.getRight());
    }

    public void postOrderTraversal() {
        postOrderTraversal(root);
    }

    private void postOrderTraversal(Node current) {
        if (current == null) {
            return;
        }
        postOrderTraversal(current.getLeft());
        postOrderTraversal(current.getRight());
        System.out.print(current.getData() + " ");
    }

    public static void main(String[] args) {
        BinaryTree tree = new BinaryTree();
        tree.insert(50);
        tree.insert(30);
        tree.insert(20);
        tree.insert(40);
        tree.insert(70);
        tree.insert(60);
        tree.insert(80);

        System.out.println("Preorder traversal:");
        tree.preOrderTraversal();
        System.out.println();

        System.out.println("Inorder traversal:");
        tree.inOrderTraversal();
        System.out.println();

        System.out.println("Postorder traversal:");
        tree.postOrderTraversal();
        System.out.println();

        Node found = tree.search(40);
        if (found != null) {
            System.out.println("Found node with data " + found.getData());
        } else {
            System.out.println("Node not found");
        }

        tree.delete(20);
        System.out.println("Inorder traversal after deleting node with data 20:");
        tree.inOrderTraversal