从上往下打印二叉树

本文介绍了一种使用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;
            }
        }
    }
}
### 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、付费专栏及课程。

余额充值