二叉树的增删以及遍历(java)

简介

二叉树的相关概念,如,树高度,节点层数,节点度数,路径,叶节点,分支节点,根节点,父节点,左节点,右节点,兄弟节点,祖先节点,子孙节点,左子树,右子树等基本概念,不再赘述。
本文主要讲解二叉树的创建,删除,以及四种遍历方式。

二叉树

二叉树是一个递归的数据结构,每个节点最多有两个子节点。
通常二叉树是二分查找树,每个节点它的值大于或者等于在它左子树节点上的值,小于或者等于在它右子树节点上的值,如下图
在这里插入图片描述
二叉树的遍历方式有4种:

  • 前序遍历:root -> left -> right
  • 中序遍历:left -> root -> right
  • 后序遍历:left ->right -> root
  • 层序遍历:按照层次遍历

上图二叉树4种遍历如下:
前序遍历:6->4->3->5->8->7->9
中序遍历:3->4->5->6->7->8->9
后续遍历:3->5->4->7->9->8->6
层次遍历:6->4->8->3->5->7->9

创建节点

为了实现二叉树,我们使用一个Node类来表示节点,节点存储int类型的值,还有对子节点的引用。

public class Node {
    int data;
    Node left;
    Node right;
    
    public Node(){}
    
    public Node(int data){
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

创建二叉树

写一个二叉树类,然后添加树的root节点

public class BinaryTree {
    Node root;
}

添加元素

我们第一次添加元素的时候,root为空,第一个元素就作为根节点,继续添加元素则遵循以下原则

  • 如果新节点小于当前的值,我们将会进入左子树
  • 如果新节点大于当前的节点。我们将会进入右子树
  • 当当前的节点是null时,我们已经到达叶子节点,我们可以添加新节点到这个位置。
    我们将会创建递归方法做添加节点操作

代码如下:

   public void addNode(int value) {
        root = addNode(root, value);
    }
   private Node addNode(Node current, int value) {
        if (current == null) {
            return new Node(value);
        }
        if (value < current.data) {
            current.left = addNode(current.left, value);
        } else if (value > current.data) {
            current.right = addNode(current.right, value);
        } else {
            return current;
        }
        return current;
    }

查找节点

  /**
     * 查找一个节点
     */
    public boolean containNode(int value) {
        return containNode(root, value);
    }

    private boolean containNode(Node current, int value) {
        if (current == null) {
            return false;
        }
        if (value == current.data) {
            return true;
        }
        return value < current.data ? containNode(current.left, value) : containNode(current.right, value);
    }

树的深度

    /**
     * 树的深度
     * 左子树或右子树最大深度+1就是树的深度
     * @return
     */
    public int deepness(){
        return deepness(root);
    }
    private int deepness(Node root){
        if(root==null){
            return -1;
        }
        int lmax = 0; //左子树的深度
        int rmax = 0; //右子树的深度
        if(root.left!=null){
            lmax = deepness(root.left);
        }
        if(root.right!=null){
            rmax = deepness(root.right);
        }
        return lmax > rmax ? lmax+1 : rmax+1;
    }

删除节点

    /**
     * 删除一个节点
     */
    public void deleteNode(int value){
        deleteNode(root,value);
    }

    private Node deleteNode(Node current, int value) {
        if (current == null) {
            return null;
        }
        if (value == current.data) {
            if (current.left == null && current.right == null) {
                return null;
            }
            if (current.left == null) {
                return current.right;
            }
            if (current.right == null) {
                return current.left;
            }
            int smallestValue = findSmallestValue(current.right);
            current.data = smallestValue;
            current.right = deleteNode(current.right, smallestValue);
            return current;
        }
        if (value < current.data) {
            current.left = deleteNode(current.left, value);
            return current;
        }
        current.right = deleteNode(current.right, value);
        return current;
    }
    private int findSmallestValue(Node root) {
        return root.left == null ? root.data : findSmallestValue(root.right);
    }

遍历树

  /**
     * 中序遍历
     */
    public void InOrderTraverse() {
        InOrderTraverse(root);
    }
    public void InOrderTraverse(Node root) {
        if (root != null) {
            InOrderTraverse(root.left);
            System.out.print(root.data+" ");
            InOrderTraverse(root.right);
        }
    }

    /**
     *前序遍历
     */
    public void PreOrderTraverse() {
        PreOrderTraverse(root);
    }
    private void PreOrderTraverse(Node root) {
        if (root != null) {
            System.out.print(root.data+" ");
            PreOrderTraverse(root.left);
            PreOrderTraverse(root.right);
        }
    }

    /**
     *后序遍历
     */
    public void PostOrderTraverse() {
        PostOrderTraverse(root);
    }
    private void PostOrderTraverse(Node root) {
        if (root != null) {
            PostOrderTraverse(root.left);
            PostOrderTraverse(root.right);
            System.out.print(root.data+" ");
        }
    }

    /**
     * 层次遍历
     */
    public void LevelOrderTraverse() {
        LevelOrderTraverse(root);
    }

    private void LevelOrderTraverse(Node root) {
        if (root == null) {
            return;
        }
        Queue<Node> nodes = new LinkedList<Node>();
        nodes.add(root);
        while(!nodes.isEmpty()) {
            Node node = nodes.remove();
            System.out.print(node.data+" ");
            if (node.left != null) {
                nodes.add(node.left);
            }

            if (node.right != null) {
                nodes.add(node.right);
            }
        }
    }

创建测试类

/**
 * @Author zsn
 * @Date 2021/6/24 14:14
 */
public class BinaryTreeTest {
    public static void main(String[] args) {
      BinaryTree tree = new BinaryTree();
      tree.addNode(6);
      tree.addNode(4);
      tree.addNode(8);
      tree.addNode(3);
      tree.addNode(5);
      tree.addNode(7);
      tree.addNode(9);

      System.out.println("1是否存在:"+tree.containNode(1));
      System.out.println("3是否存在:"+tree.containNode(3));

      System.out.println("前序遍历:");
      tree.PreOrderTraverse();
      System.out.println();


      System.out.println("中序遍历:");
      tree.InOrderTraverse();
      System.out.println();

      System.out.println("后序遍历:");
      tree.PostOrderTraverse();
      System.out.println();

      System.out.println("层次遍历:");
      tree.LevelOrderTraverse();

      //删除元素
      tree.deleteNode(9);
      System.out.println();

      System.out.println("删除后的层次遍历:");
      tree.LevelOrderTraverse();
    }
}

运行结果如下:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值