二叉树Java实现

二叉树Java实现

养成好习惯,先上思维导图
在这里插入图片描述

1-数组List

以ArrayList为例,它的底层是通过list数组进行实现的,所以可以通过这个点进行分析!

优点:数组能够通过下表直接进行访问,也可以通过各种查找方法进行查找!查找可以十分快速。

缺点:由于list在增添或删除时(插入元素),过程中需要对数组进行扩容,这个操作会调用ArrayList数组中的grow方法,本质上会在内存中开辟新的数组,耗费时间!

2-链表Linked

优点:链表可以进行十分快速的增添与删除,得益于链表自身储存下一个元素地址的特点,不需要在内存中开辟新的空间,元素如果没有对象指向时,会被虚拟机进行垃圾回收。

缺点:查询速度慢,链表的查询只能够从头开始进行查询,直到找到Key的位置。

3-树Tree!

在这里插入图片描述

以上图为例,通俗易懂的说明树的基础概念:

  • 根节点:node1,一颗树开始的地方;
  • 叶子结点:node5,node4,node2,一棵树没有后继子结点的结点,也就是末端
  • 子节点:node3,后继的结点
  • 父节点:node3,有后继结点的结点

说明:子节点与父结点是相对的概念,一个子节点也可以是其他元素的父节点

遍历方式(默认先左后右进行遍历):

  • 前序遍历:以上图为例,输出的顺序为12354
  • 中序遍历:以上图为例,输出的顺序为21534
  • 后续遍历:以上图为例,输出的顺序为25431

说明:在代码实现过程中,遍历方式的改变,仅仅改变了输入语句的位置,同时进行了递归调用

4-Java代码实现

package tree;

/**
 * 这是一个二叉树
 */
public class BinaryTreeDemo {
    public static void main(String[] args) {
        // 准备工作1:新建一个二叉树
        binaryTree binaryTree = new binaryTree();
        // 准备工作2:创建结点
        HeroNode root = new HeroNode(1, "宋江");
        HeroNode node2 = new HeroNode(2, "吴用");
        HeroNode node3 = new HeroNode(3, "卢俊义");
        HeroNode node4 = new HeroNode(4, "林冲");
        HeroNode node5 = new HeroNode(5, "海绵宝宝");
        // 1.手动形成树结构
        root.setLeft(node2);
        root.setRight(node3);
        node3.setRight(node4);
        node3.setLeft(node5);
        binaryTree.setRoot(root);// 将根节点加入二叉树

        // 2.遍历
        // 2.1前序遍历
        System.out.println("- - 前序遍历- - ");
        binaryTree.preOrder(); // 1234
        // 2.2中序遍历
        System.out.println("- - 中序遍历- - ");
        binaryTree.infixOrder(); // 2143
        // 2.2前后遍历
        System.out.println("- - 后序遍历- - ");
        binaryTree.postOrder(); // 2431

        // 另一个练习,如果有一个结点元素Node(5,"海绵宝宝")被加入到了3号结点的左边时
        System.out.println("- - 新结点5加入后的前序遍历- - ");
        binaryTree.preOrder(); // 12354
        System.out.println("- - 新结点5加入后的中序遍历- - ");
        binaryTree.infixOrder(); // 21543
        System.out.println("- - 新结点5加入后的后序遍历- - ");
        binaryTree.postOrder(); // 25431

    }
}

 // 二叉树
class binaryTree{
    private HeroNode root;


     public HeroNode getRoot() {
         return root;
     }

     public void setRoot(HeroNode root) {
         this.root = root;
     }

     // 前序遍历
     public void preOrder(){
         if (this.root != null){
             this.root.preOrder(); // 在Tree中调用了结点的遍历方法
         }else {
             System.out.println("根节点为空,无法进行遍历");
         }
     }

     // 中序遍历
     public void infixOrder(){
         if (this.root != null){
             this.root.infixOrder(); // 在Tree中调用了结点的遍历方法
         }else {
             System.out.println("根节点为空,无法进行遍历");
         }
     }

     // 后序遍历
     public void postOrder(){
         if (this.root != null){
             this.root.postOrder(); // 在Tree中调用了结点的遍历方法
         }else {
             System.out.println("根节点为空,无法进行遍历");
         }
     }
 }

// 结点类 HeroNode
class HeroNode{
    private int no; // 元素序列号
    private String name; // 结点数据
    private HeroNode left; // 二叉树的左边
    private HeroNode right; // 二叉树的右边

    public HeroNode(int no,String name) {
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public HeroNode getLeft() {
        return left;
    }

    public void setLeft(HeroNode left) {
        this.left = left;
    }

    public HeroNode getRight() {
        return right;
    }

    public void setRight(HeroNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    // 前序遍历方法
    public void preOrder(){
        System.out.println(this); // 输出父节点
        // 遍历二叉树的左边
        if (this.left != null){
            this.left.preOrder();// 向左递归
        }
        // 遍历右边
        if (this.right !=null){
            this.right.preOrder(); // 向右递归
        }
    }

    // 中序遍历
    public void infixOrder(){
        // 遍历二叉树的左边
        if (this.left != null){
            this.left.infixOrder();
        }

        System.out.println(this);

        // 遍历二叉树的右边
        if (this.right != null){
            this.right.infixOrder();
        }
    }

    // 后序遍历
    public void postOrder(){
        // 遍历二叉树的左边
        if (this.left != null){
            this.left.postOrder();
        }

        // 遍历二叉树的右边
        if (this.right != null){
            this.right.postOrder();
        }
        System.out.println(this);
    }
}

解释:

  • 遍历的具体方法是写在HeroNode中,在binaryTree中,调用了HeroNode提供的遍历方法
  • 二叉树结构通过手动实现结点与结点之间的关系。

总结

开始树的学习阶段,需要补充的还有快速排序算法复杂度分析,最差情况与最好情况,被考过!怕了怕了!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值