二叉树的遍历方式(前序遍历、中序遍历、后序遍历的递归与非递归的Java实现)

预备知识点

Java自定义类

我们可以把的类型为两种:
第一种,Java为我们提供好的类,如Scanner类,Random类等,这些已存在的类中包含了很多的方法与属性,可供我们使用。
第二种,我们自己创建的类,按照类的定义标准,可以在类中包含多个方法与属性,来供我们使用。

这里我们主要介绍第二种情况的简单使用。

自定义类的概述
我们在Java中,将现实生活中的事物抽象成了代码。这时,我们可以使用自定义的数据类型(类)来描述(映射)现实生活中的事物。

类,它是引用数据类型,与之前学习的所有引用数据类型相同,自定义类也是一种数据类型只是自定义类型并非Java为我们预先提供好的类型,而是我们自己定义的一种引用数据类型用来描述一个事物。

类的定义与使用

我们就拿一部手机进行分析,它能用来做什么呢?它可以打电话,上网,聊微信等,这些就是手机所提供的功能,也就是方法;手机也有它的特征,如颜色、尺寸大小、品牌型号等,这些就是手机的特征,也就是属性。

通过类的定义格式,来进行手机类的描述,如下所示

public class Phone {
   
    /*
     * 属性
     */
    String brand;// 品牌型号
    String color;// 颜色
    double size; // 尺寸大小
}

上述代码,就是创建一个类的的过程,类的名称我们给起名为Phone,类中包含了三个属性(brand品牌型号、color颜色、size尺寸大小)。注意,类中定义的属性没有个数要求。

Phone类定义好后,我们就可以使用这个类了,使用方式和使用引用数据类型Scanner类相似。格式如下:

  • 导包:我们将所有的类放到同一个文件夹下,可以避免导包。
  • 创建对象:数据类型 变量名 = new 数据类型();
  • 调用方法:目前我们定义的自定义类不涉及方法,只是属性(自定义类中的方法部分在面向对象部分讲解)
  • 访问属性:变量名.属性 (这是当前的方式,后期会采取调用方法的方式替代掉直接访问的方式来完成对属性的访问。)

当有了Phone数据类型的变量后,我们就可以使用Phone类中的属性了。对属性的访问我们来演示一下,如下所示:

public class Test {
   
    public static void main(String[] args) {
   
        //定义了一个Phone类型的变量p
        Phone p = new Phone();
        /*
         * 通过p,使用Phone中的属性
         */
        //访问p中的brand品牌属性
       p.brand = "苹果X"; 
       //访问p中的color颜色属性
        p.color = "白色"; 
        //访问p中的size尺寸大小属性
        p.size = 6.5; 

       System.out.println("手机品牌为" + p.brand );
       System.out.println("手机颜色为" + p.color );
       System.out.println("手机尺寸大小为" + p.size );
    }
}

下面以构造完全二叉树为例,再次理解自定义类:

树节点的构造为:

/**
 * 构造树节点
 */
public class Tree {
   
    //节点的值
    int value;
    //节点的左子节点
    Tree left;
    //节点的右子节点
    Tree right;
    //类的有参构造方法
    public Tree(int j){
   
        this.value=j;
    }
}


完全二叉树的构造如下:

public class Main {
   

    public static void main(String[] args) {
   
        //以数组形式构造Test类的对象,tests是一个可以容纳了三个Test对象的一维数组
        Tree[] tests = new Tree[10];
        //遍历数组的长度,分别进行赋值
        for(int i=0;i<tests.length;i++
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以为您解答这个问题。首先,我们需要先了解二叉树遍历方式包括前序遍历中序遍历后序遍历。其中,前序遍历是先访问根节点,然后访问左子树和右子树;中序遍历是先访问左子树,然后访问根节点和右子树;后序遍历是先访问左子树和右子树,最后访问根节点。 接下来,我们分别介绍递归遍历非递归遍历实现思路。 1. 递归遍历 递归遍历二叉树的思路较为简单,我们只需要按照遍历方式的顺序递归访问每个节点即可。具体实现如下: 前序遍历: ```C++ void preOrderTraversal(TreeNode* root) { if(root != nullptr) { cout << root->val << " "; preOrderTraversal(root->left); preOrderTraversal(root->right); } } ``` 中序遍历: ```C++ void inOrderTraversal(TreeNode* root) { if(root != nullptr) { inOrderTraversal(root->left); cout << root->val << " "; inOrderTraversal(root->right); } } ``` 后序遍历: ```C++ void postOrderTraversal(TreeNode* root) { if(root != nullptr) { postOrderTraversal(root->left); postOrderTraversal(root->right); cout << root->val << " "; } } ``` 2. 非递归遍历 非递归遍历二叉树需要借助栈结构来实现。我们先将根节点入栈,然后按照遍历方式的顺序依次访问每个节点,并将其子节点入栈。具体实现如下: 前序遍历: ```C++ void preOrderTraversal(TreeNode* root) { stack<TreeNode*> st; if(root != nullptr) { st.push(root); } while(!st.empty()) { TreeNode* node = st.top(); st.pop(); cout << node->val << " "; if(node->right != nullptr) { st.push(node->right); } if(node->left != nullptr) { st.push(node->left); } } } ``` 中序遍历: ```C++ void inOrderTraversal(TreeNode* root) { stack<TreeNode*> st; TreeNode* node = root; while(node != nullptr || !st.empty()) { while(node != nullptr) { st.push(node); node = node->left; } node = st.top(); st.pop(); cout << node->val << " "; node = node->right; } } ``` 后序遍历: ```C++ void postOrderTraversal(TreeNode* root) { stack<TreeNode*> st; TreeNode* node = root; TreeNode* lastVisited = nullptr; while(node != nullptr || !st.empty()) { while(node != nullptr) { st.push(node); node = node->left; } node = st.top(); if(node->right == nullptr || node->right == lastVisited) { st.pop(); cout << node->val << " "; lastVisited = node; node = nullptr; } else { node = node->right; } } } ``` 以上就是二叉树遍历递归非递归实现思路和代码。需要注意的是,这里使用的是二叉树节点的结构体,其中包含左子树、右子树和节点值。同时,为了实现非递归遍历,我们需要借助栈结构来存储节点信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值