从上往下打印二叉树

本文介绍了一种使用Java实现的二叉树结构及其遍历方法,包括递归与非递归的前序、中序、后序遍历,并详细展示了按层遍历的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。

import java.util.ArrayList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
            ArrayList<TreeNode>  listNode=new ArrayList<TreeNode> ();
        ArrayList<Integer>  listVal=new ArrayList<Integer> ();
        if(root==null)
            return listVal;
        listNode.add(root);
        listVal.add(root.val);
        for(int i=0;i<listNode.size();i++){
          TreeNode node=  listNode.get(i);
            if(node.left!=null){
                listNode.add(node.left);
                listVal.add(node.left.val);
            }
            if(node.right!=null){
                listNode.add(node.right);
                  listVal.add(node.right.val);
        }

        }

        return listVal;
    }

}
package com.struct.tree.secondeTree;

import java.util.ArrayList;
import java.util.Stack;

public class Tree
{
    private static final String left = "leftSon";
    private static final String right = "rightSon";
    public static void main(String[] args)
    {
        TreeType treeType = new TreeType();
        treeType.init("A");
        treeType.add("B", "A", left);
        treeType.add("C", "A", right);
        treeType.add("D", "B", left);
        treeType.add("E", "B", right);
        treeType.add("F", "C", left);
        treeType.add("G", "C", right);
        treeType.add("H", "D", left);
        treeType.add("I", "F", right);
        System.out.println("前序遍历:");
        treeType.DLR(treeType.getRoot());
        System.out.println();
        System.out.println("非递归前序遍历: ");
        treeType.iteratorPre(treeType.getRoot());
        System.out.println();
        System.out.println("中序遍历:");
        treeType.LDR(treeType.getRoot());
        System.out.println();
        System.out.println("非递归中序遍历: ");
        treeType.iteratorMid(treeType.getRoot());
        System.out.println();
        System.out.println("后续遍历: ");
        treeType.LRD(treeType.getRoot());
        System.out.println();
        System.out.println("非递归后续遍历: ");
        treeType.iteratorLat(treeType.getRoot());
        System.out.println();
        System.out.println("按层遍历: ");
        treeType.level(treeType.getRoot());
        System.out.println();
        System.out.println("安层遍历2: ");
        treeType.showlevel();
        System.out.println();
        System.out.println("树的深度:");
        //树的深度
        System.out.println(treeType.dept(treeType.getRoot()));
    }

}

class Node{
    private Object value;   //结点数据
    private Node left;  //左指针
    private Node right; //右指针
    public Node(Object va)
    {
        this.value = va;
        left = null;
        right = null;
    }

    public Object getValue(){
        return value;
    }

    public Node getLeft(){
        return this.left;
    }

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

    public Node getRight(){
        return this.right;
    }

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

}

class TreeType{
    private Node root;
    private static int MaxLen=20;
    public Node init(Object val){
            root = new Node(val);
            return root;
    }

    public Node getRoot(){
        return root;
    }

    public void add(Object val,Object parent,String direction){

        Node parentNode=getParent(root, parent);
        Node newNode = new Node(val);
        if(parentNode==null){
            System.out.println("what your insert is wrong");
            return;
        }

        switch (direction)
        {
            case "leftSon":
                if(parentNode.getLeft()!=null){
                    System.out.println("leftson is not null");
                }
                parentNode.setLeft(newNode);
                break;
            case "rightSon":
                if(parentNode.getRight()!=null){
                    System.out.println("rightson is not null");
                }
                parentNode.setRight(newNode);                
                break;
        }
    }

    public Node getParent(Node root,Object parent){

        Node p;
        Node temp = root;
        if(root==null){
            return null;
        }else {
            if(temp.getValue().equals(parent)){
                return temp;
            }else if ((p=getParent(temp.getLeft(), parent))!=null) {
                return p;
            }else if ((p=getParent(temp.getRight(), parent))!=null) {
                return p;
            }else {
                return null;
            }
        }
    }

    //显示节点
    public void show(Node parentNode){
        if(parentNode==null){
            System.out.println("does not exits");
        }
        System.out.print(parentNode.getValue()+" ");
    }

    //前序遍历
    public void DLR(Node node){
        if(node!=null){
            show(node);
            DLR(node.getLeft());
            DLR(node.getRight());
        }
    }

    //中序遍历
    public void LDR(Node node){
        if(node!=null){
            LDR(node.getLeft());
            show(node);
            LDR(node.getRight());
        }
    }

    //后序遍历
    public void LRD(Node node){
        if(node!=null){
            LRD(node.getLeft());
            LRD(node.getRight());
            show(node);
        }
    }

    //按层遍历
    public void level(Node node){
        Node pNode;
        Node[] q = new Node[MaxLen];
        int head=0;
        int tail=0;
        if(node!=null){
            tail=(tail+1);
            q[tail]=node;
        }
        while(head!=tail){
            head=(head+1);
            pNode=q[head];
            show(pNode);
            if(pNode.getLeft()!=null){
                tail=(tail+1);
                q[tail]=pNode.getLeft();
            }
            if(pNode.getRight()!=null){
                tail=(tail+1);
                q[tail]=pNode.getRight();
            }
        }
    }



    //按曾遍历2
    public static ArrayList<String> PrintFromTopToBottom(Node root) {
            ArrayList<Node>  listNode=new ArrayList<Node> ();
            ArrayList<String>  listVal=new ArrayList<String> ();
            if(root==null)
                return listVal;
            listNode.add(root);
            listVal.add((String) root.getValue());
            for(int i=0;i<listNode.size();i++){
                Node node=  listNode.get(i);
                if(node.getLeft()!=null){
                    listNode.add(node.getLeft());
                    listVal.add((String)node.getLeft().getValue());
                }
                if(node.getRight()!=null){
                    listNode.add(node.getRight());
                      listVal.add((String)node.getRight().getValue());
            }

            }

            return listVal;
        }

      //按曾遍历2
    public void showlevel(){
       ArrayList<String> arrayList = PrintFromTopToBottom(root);
       for(String a:arrayList){
           System.out.print(a+" ");
        }
    }



    //非递归前序遍历
    public void iteratorPre(Node node){
        Stack<Node> stack = new Stack<>();
        if(node!=null){
            stack.push(node);
            while(!stack.empty()){
                node = stack.pop();
                show(node);
                if(node.getRight()!=null){
                    stack.push(node.getRight());
                    //为什么p.getLeft() 在后,getRight()在前应为while 
                        //循环第一句就是pop visit所以要把left放上,先访问。之中方法是即压即访问法。
                }
                if(node.getLeft()!=null){
                    stack.push(node.getLeft());
                }
            }
        }
    }

    //非递归中序遍历
    public void iteratorMid(Node p){
        Stack<Node> stack = new Stack<Node>();    
        Node node = p;    
        while (node != null || stack.size() > 0) {    
            while (node != null) {    
                stack.push(node);    
                node = node.getLeft();    
            }    
            if (stack.size() > 0) {    
                node = stack.pop();    
                show(node);     
                node = node.getRight();    
            }    
        }    
    }

    //非递归后续遍历
    public void iteratorLat(Node p){
        Node q = p;    
        Stack<Node> stack = new Stack<Node>();    
        while (p != null) {    
            // 左子树入栈    
            for (; p.getLeft() != null; p = p.getLeft())    
                stack.push(p);    
            // 当前节点无右子或右子已经输出    
            while (p != null && (p.getRight() == null || p.getRight() == q)) {    
                show(p);    
                q = p;// 记录上一个已输出节点    
                if (stack.empty())    
                    return;    
                p = stack.pop();    
            }    
            // 处理右子    
            stack.push(p);    
            p = p.getRight();    
        }    
    }



    //深度
    public int dept(Node node){
        int deptleft;
        int deptright;
        if(node==null){
            return 0;
        }else {
            deptleft=dept(node.getLeft());
            deptright=dept(node.getRight());
            if(deptleft>=deptright){
              deptleft++;
              return deptleft;
            }else {
              deptright++;
              return deptright;
            }
        }
    }
}
资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 “STC单片机电压测量”是一个以STC系列单片机为基础的电压检测应用案例,它涵盖了硬件电路设计、软件编程以及数据处理等核心知识点。STC单片机凭借其低功耗、高性价比和丰富的I/O接口,在电子工程领域得到了广泛应用。 STC是Specialized Technology Corporation的缩写,该公司的单片机基于8051内核,具备内部振荡器、高速运算能力、ISP(在系统编程)和IAP(在应用编程)功能,非常适合用于各种嵌入式控制系统。 在源代码方面,“浅雪”风格的代码通常简洁易懂,非常适合初学者学习。其中,“main.c”文件是程序的入口,包含了电压测量的核心逻辑;“STARTUP.A51”是启动代码,负责初始化单片机的硬件环境;“电压测量_uvopt.bak”和“电压测量_uvproj.bak”可能是Keil编译器的配置文件备份,用于设置编译选项和项目配置。 对于3S锂电池电压测量,3S锂电池由三节锂离子电池串联而成,标称电压为11.1V。测量时需要考虑电池的串联特性,通过分压电路将高电压转换为单片机可接受的范围,并实时监控,防止过充或过放,以确保电池的安全和寿命。 在电压测量电路设计中,“电压测量.lnp”文件可能包含电路布局信息,而“.hex”文件是编译后的机器码,用于烧录到单片机中。电路中通常会使用ADC(模拟数字转换器)将模拟电压信号转换为数字信号供单片机处理。 在软件编程方面,“StringData.h”文件可能包含程序中使用的字符串常量和数据结构定义。处理电压数据时,可能涉及浮点数运算,需要了解STC单片机对浮点数的支持情况,以及如何高效地存储和显示电压值。 用户界面方面,“电压测量.uvgui.kidd”可能是用户界面的配置文件,用于显示测量结果。在嵌入式系统中,用
资源下载链接为: https://pan.quark.cn/s/abbae039bf2a 在 Android 开发中,Fragment 是界面的一个模块化组件,可用于在 Activity 中灵活地添加、删除或替换。将 ListView 集成到 Fragment 中,能够实现数据的动态加载与列表形式展示,对于构建复杂且交互丰富的界面非常有帮助。本文将详细介绍如何在 Fragment 中使用 ListView。 首先,需要在 Fragment 的布局文件中添加 ListView 的 XML 定义。一个基本的 ListView 元素代码如下: 接着,创建适配器来填充 ListView 的数据。通常会使用 BaseAdapter 的子类,如 ArrayAdapter 或自定义适配器。例如,创建一个简单的 MyListAdapter,继承自 ArrayAdapter,并在构造函数中传入数据集: 在 Fragment 的 onCreateView 或 onActivityCreated 方法中,实例化 ListView 和适配器,并将适配器设置到 ListView 上: 为了提升用户体验,可以为 ListView 设置点击事件监听器: 性能优化也是关键。设置 ListView 的 android:cacheColorHint 属性可提升滚动流畅度。在 getView 方法中复用 convertView,可减少视图创建,提升性能。对于复杂需求,如异步加载数据,可使用 LoaderManager 和 CursorLoader,这能更好地管理数据加载,避免内存泄漏,支持数据变更时自动刷新。 总结来说,Fragment 中的 ListView 使用涉及布局设计、适配器创建与定制、数据绑定及事件监听。掌握这些步骤,可构建功能强大的应用。实际开发中,还需优化 ListView 性能,确保应用流畅运
### C语言实现从上到下打印二叉树 要实现从上到下的顺序打印二叉树节点,可以采用层次遍历的方法。这种方法通常借助队列来完成,因为队列具有先进先出的特点,能够按照加入的顺序依次处理每个节点。 以下是完整的代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树节点结构体 typedef struct TreeNode { int data; struct TreeNode* lchild; struct TreeNode* rchild; } TreeNode; // 创建新节点 TreeNode* create_node(int value) { TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); node->data = value; node->lchild = NULL; node->rchild = NULL; return node; } // 层次遍历并打印二叉树 void level_order_traversal(TreeNode* root) { if (!root) return; // 如果根为空,则直接返回 // 初始化队列 TreeNode** queue = (TreeNode**)malloc(100 * sizeof(TreeNode*)); // 假设最多有100个节点 int front = 0, rear = 0; // 将根节点入队 queue[rear++] = root; while (front != rear) { // 当队列不为空时继续循环 TreeNode* current = queue[front++]; // 取出队首元素 printf("%d ", current->data); // 输出当前节点的数据 // 左子节点存在则将其入队 if (current->lchild) { queue[rear++] = current->lchild; } // 右子节点存在则将其入队 if (current->rchild) { queue[rear++] = current->rchild; } } free(queue); // 释放队列内存 } int main() { // 构建一个简单的二叉树作为测试数据 TreeNode* root = create_node(1); root->lchild = create_node(2); root->rchild = create_node(3); root->lchild->lchild = create_node(4); root->lchild->rchild = create_node(5); // 调用层次遍历函数 printf("Level order traversal of binary tree is:\n"); level_order_traversal(root); return 0; } ``` 上述代码实现了通过队列进行层次遍历的功能[^1]。具体来说,程序会逐层访问二叉树中的每一个节点,并按从左至右的顺序输出其值。如果某个节点还有子节点,则这些子节点会被添加到队列中等待后续处理。 #### 关键点说明: - **队列的作用**:用于存储待访问的节点,确保每次总是优先访问较早进入队列的节点。 - **边界条件**:当输入的二叉树为空时,应立即退出而不执行任何操作。 - **动态分配与释放资源**:为了支持不同大小的二叉树,在实际应用中可能需要更灵活地管理队列的空间大小以及及时释放不再使用的内存区域。 此方法的时间复杂度为O(n),其中n表示二叉树中总的节点数;空间复杂度同样也是O(n),因为在最坏情况下整个二叉树的所有节点都可能会被暂时存放在队列里[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值