zoukankan      html  css  js  c++  java
  • 用Java实现一个二叉树

    介绍

    使用Java实现一个int值类型的排序二叉树

    二叉树

    二叉树是一个递归的数据结构,每个节点最多有两个子节点。
    通常二叉树是二分查找树,每个节点它的值大于或者等于在它左子树节点上的值,小于或者等于在它右子树节点上的值,如下图

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

    package com.java.node.BinaryTree;
    public class Node {
        int data;
        Node left;
        Node right;
        public Node(int data) {
            this.data = data;
            this.left = null;
            this.right = null;
        }
    }
    

    然后添加树的root节点

    package com.java.node.BinaryTree;
    public class BinaryTree {
        Node root;
    }
    

    通常的操作

    添加节点

    首先我们必须找到新节点的位置,是为了保持树排序。我们必须从root节点开始,必须遵循下面的规则:

    • 如果新节点小于当前的值,我们将会进入左子树
    • 如果新节点大于当前的节点。我们将会进入右子树
    • 当当前的节点是null时,我们已经到达叶子节点,我们可以添加新节点到这个位置。
      我们将会创建递归方法做添加节点操作
        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 void addNode(int value) {
            root = addNode(root, value);
        }
    

    可以使用方法创建一个二叉树了

    public BinaryTree createBinaryTree() {
            BinaryTree bt = new BinaryTree();
            bt.addNode(6);
            bt.addNode(4);
            bt.addNode(8);
            bt.addNode(10);
            return bt;
        }
    

    查找一个节点

        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);
        }
        public boolean containNode(int value) {
            return containNode(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);
        }
    

    遍历树

    我们将以不同的方式遍历树,以depth-first,breadth-first方式遍历树。
    以Depth-First遍历树
    Depth-first查询是一种在查询兄弟节点之前,尽可能的查询每个子节点。
    in-order,pre-order,post-order方式都是以depth-first方式遍历树的。

    in-order遍历是首先遍历左子树,然后root节点,最后是右子树。

        public void traverseInOrder(Node root) {
            if (root != null) {
                traverseInOrder(root.left);
                System.out.println(root.data);
                traverseInOrder(root.right);
            }
        }
    

    pre-order遍历首先是root节点,然后是左子树,最后是右子树。

    public void traversePreOrder(Node root) {
            if (root != null) {
                System.out.println(root.data);
                traversePreOrder(root.left);
                traversePreOrder(root.right);
            }
        }
    

    post-order遍历首先是遍历左子树,然后是右子树,最后是root节点。

    public void traversePostOrder(Node root) {
            if (root != null) {
                traversePostOrder(root.left);
                traversePostOrder(root.right);
                System.out.println(root.data);
            }
        }
    

    以Breadth-First遍历
    它在遍历下一级的节点之前,会遍历当前级的所有节点。
    这种类型的遍历也叫做level-order,遍历树从root节点开始,从左到右。
    为了实现,使用队列来存储每个级别的节点。我们将会从列表中获取每个节点。然后添加他的子节点到队列中。

    public void traverseLevelOrder(Node root) {
            if (root == null) {
                return;
            }
            Queue<Node> nodes = new LinkedList<Node>();
            nodes.add(root);
            while(!nodes.isEmpty()) {
                Node node = nodes.remove();
                System.out.println(node.data);
                if (node.left != null) {
                    nodes.add(node.left);
                }
    						
                if (node.right != null) {
                    nodes.add(node.right);
                }
            }
        }
    
  • 相关阅读:
    Linux-第一天
    Hadoop学习10--常用命令记录帖
    C# asp.net repeater实现排序功能,自动排序,点击头部排序,点击列排序
    图片与字符之间的转换
    兼容浏览器 div固定浏览器窗口底部 浮动div
    解决QQ未启用状态,QQ留言图标未启用
    C#Cookie操作类,删除Cookie,给Cookie赋值
    vs2008bin下Debug bll Release文件 obj下的Debug bll Release文件区别
    asp.net限制了上传文件大小为..M,解决方法
    多文件上传ajax jquery
  • 原文地址:https://www.cnblogs.com/yandufeng/p/10845118.html
Copyright © 2011-2022 走看看