`

编程之美-分层遍历二叉树

阅读更多

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class LevelTraverseBinaryTree {

    /**
     * 编程之美 分层遍历二叉树
     * 之前已经用队列实现过二叉树的层次遍历,但这次要求输出换行,因此要标记什么时候要换行:
     * 用inCount记录某层有多少个元素,outCount记录当前输出了多少个元素;当inCount==outCount时,就说明某层元素已经完全输出,此时应该换行(outCount清零)
     * 此外,观察发现,当第K层元素全部出队(并已将各自左右孩子入队)后,队列里面刚好存放了第K+1层的所有元素,不多不少,所以有:inCount = queue.size();
     * 
     * 书上的扩展问题也很有意思(从下往上分层输出),既然是反过来输出,第一反应是利用栈
     * 但同时又要记录何时换行(每行有多少个元素),只好用ArrayList模拟一个“伪栈”:
     * 1、第一步操作和“从上往下分层输出”是类似的:从root开始遍历,并将所有元素放入“队列”(ArrayList),用-1表示一层的结束
     * 2、输出。不是从队头开始,而是从队尾开始,依次输出
     * 分析到这里,这里面的ArrayList定义为“双向队列”更合适
     */
    public static void main(String[] args) {
        /*
                            __1__
                           /     \
                        __2__     3__
                       /     \       \
                      4     __5__     6
                           7     8
         */
        int[] src = { 1, 2, 3, 4, 5, 0, 6, 0, 0, 7, 8 };
        LevelTraverseBinaryTree data = new LevelTraverseBinaryTree();
        Node root = data.createTree(src);
        data.traverseByLevelFromTop(root);
        System.out.println();
        data.traverseByLevelFromBottom(root);
    }
    
    /*
     从上往下分层输出
        1 
        2 3 
        4 5 6 
        7 8 
     */
    public void traverseByLevelFromTop(Node node) {
        if (node == null) {
            return;
        }
        LinkedList<Node> queue = new LinkedList<Node>();
        queue.addLast(node);
        int inCount = 1;
        int outCount = 0;
        while (!queue.isEmpty()) {
            Node curNode = queue.pollFirst();
            System.out.print(curNode.getData() + " ");
            outCount++;
            if (curNode.getLeft() != null) {
                queue.addLast(curNode.getLeft());
            }
            if (curNode.getRight() != null) {
                queue.addLast(curNode.getRight());
            }
            if (outCount == inCount) {
                System.out.println();
                inCount = queue.size();
                outCount = 0;
            }
        }
    }
    
    /*
    从下往上分层输出
        7 8 
        4 5 6 
        2 3 
        1 
    */
    public void traverseByLevelFromBottom(Node node) {
        if (node == null) {
            return;
        }
        List<Node> list = new ArrayList<Node>();
        list.add(node);
        list.add(new Node(-1));     //-1表示一层结束,打印时要换行
        int i = 0;
        int size = list.size();
        while (i < size) {
            Node curNode = list.get(i);
            
            /*交换下面这两个操作,可实现输出:
                8 7 
                6 5 4 
                3 2 
                1
             */
            if (curNode.getRight() != null) {
                list.add(curNode.getRight());
            } 
            if (curNode.getLeft() != null) {
                list.add(curNode.getLeft());
            }
            
            i++;
            if (i == size) {
                if (curNode.getData() != -1 && curNode.getLeft() == null && curNode.getRight() == null) {   //已经遍历到最底层的最后一个元素,结束循环
                    break;
                }
                size = list.size();
                list.add(new Node(-1));     
            }
        }
        
        //从后往前遍历,相当于“栈”
        for (size = list.size(), i = size - 1; i >=0; i--) {
            int val = list.get(i).getData();
            if (val == -1) {
                System.out.println();
            } else {
                System.out.print(val + " ");
            }
        }
    }
    

    public Node createTree(int[] data){  
        List<Node> nodeList=new ArrayList<Node>();  
        for(int each:data){  
            Node n=new Node(each);  
            nodeList.add(n);  
        }  
        int lastRootIndex=data.length/2-1;  
        for(int i=0;i<=lastRootIndex;i++){  
            Node root=nodeList.get(i);  
            Node left=nodeList.get(i*2+1);  
            if(left.getData()!=0){  
                root.setLeft(left);  
            }else{  
                root.setLeft(null);  
            }  
            if(i*2+2<data.length){  
                Node right=nodeList.get(i*2+2);  
                if(right.getData()!=0){  
                    root.setRight(right);  
                }else{  
                    root.setRight(null);  
                }  
            }  
              
        }  
        Node root=nodeList.get(0);  
        return root;  
    }  
}

class Node {
    
    int data;
    Node left;
    Node right;

    Node(int data) {
        this.data = data;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public Node getLeft() {
        return left;
    }

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

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }
}
1
3
分享到:
评论

相关推荐

    二叉树算法

    在实际编程中,二叉树的遍历算法是解决问题的基础,例如在搜索最长字符串、计算二叉树的最大距离、重建二叉树、分层遍历二叉树等问题时都会用到。 此外,二叉树相关的知识还包括但不限于深度优先搜索(DFS)用于...

    二叉树遍历

    在"遍历二叉树的神级方法"这个文件中,可能包含了各种优化的遍历策略或算法,比如非递归的 Morris遍历或线程化遍历,这些方法在某些情况下能提高效率或节省空间。Morris遍历利用了空指针,无需额外的空间就能完成...

    分层建立多叉树及分层遍历输出

    本文将深入探讨如何使用C++语言分层建立一个多叉树,并进行分层遍历输出。在此过程中,我们将特别关注在奇数节点位置插入偶数节点的策略,以满足特定的输出格式要求。 首先,我们需要理解多叉树的概念。与二叉树...

    递归和非递归建立树和树的前,中,后,分层遍历

    本主题将深入探讨如何使用递归和非递归方法来建立树,并实现前序、中序、后序以及分层遍历。 **一、递归与非递归建立树** 1. **递归建立树**:递归是一种自顶向下的解决问题的方法,它通过函数调用自身来实现。在...

    二叉树题目列表1

    这是通过一次遍历二叉树来实现的,通常使用中序遍历的方法,因为BST的中序遍历结果是有序的。在遍历过程中,可以将相邻的节点连接起来形成链表,同时处理头尾节点以构建完整的链表。 以下是一些关于二叉树的常见...

    数据结构中二叉树各种题型详解及程序.docx

    4. **分层遍历**(层次遍历):使用队列进行广度优先搜索,从根节点开始,每层节点依次加入队列,然后逐个访问并移除。这可以用于显示二叉树的层次结构。 5. **将二叉查找树(BST)变为有序的双向链表**:通过中序...

    算法-理论基础- 二叉树- 顺序存储结构(包含源程序).rar

    本资源“算法-理论基础- 二叉树- 顺序存储结构(包含源程序)”着重探讨了二叉树的顺序存储结构及其相关的算法实现。下面将详细介绍这个主题中的关键知识点。 一、二叉树基础 1. 定义:二叉树是由n(n≥0)个有限...

    数据结构试验3二叉树建立,遍历等

    二叉树常用于实现搜索、排序和其他操作,因为它们提供了对数据的分层访问,这使得查找和插入操作的时间复杂度能够达到O(log n)。 在建立二叉树的过程中,通常有两种方法:前序遍历、中序遍历和后序遍历。这些遍历...

    cpp代码-树和二叉树

    3. 图像处理:树结构可以用于图像的分层表示,二叉树常用于图像的分割或识别。 4. 数据库索引:B树和B+树作为数据库索引结构,提供高效的查询性能。 5. 编译器:词法分析和语法分析中的解析树和抽象语法树是树结构...

    二叉树真正树状分层显示

    3. **层次遍历**:要分层显示二叉树,最常用的方法是层次遍历(广度优先搜索,BFS)。这里我们可以使用队列作为辅助数据结构,将根节点入队,然后每次出队一个节点,将其左右子节点(如果存在)入队。这样可以保证...

    考研杭电计算机复试面试:专业课

    1. 互联网的分层结构 - 通常分为应用层、传输层、网络层、数据链路层和物理层。 - 每层都有其特定的功能和协议,如传输层的TCP/UDP协议、网络层的IP协议、数据链路层的以太网协议等。 2. 数据链路层和网络层的...

    二叉树习题

    遍历二叉树有四种基本方法: 1. 先根遍历:先访问根结点,然后分别遍历左子树和右子树。 2. 中根遍历:先遍历左子树,然后访问根结点,最后遍历右子树。 3. 后根遍历:先遍历左子树和右子树,最后访问根结点。 4. ...

    二叉树及其运算.pdf

    4. 后序遍历:非递归地遍历二叉树,后序遍历的顺序是左子树、右子树、根节点。 实验中还提出了附加要求,如计算二叉树的节点总数和叶子节点数,以及设计一个创新的与树相关的题目并解决。这些要求有助于提升学生的...

    基于Java的二叉树层序遍历打印实现.docx

    2. **分层遍历并返回List&lt;List&lt;Integer&gt;&gt;(剑指offer32-Ⅱ/LeetCode102)**: 在此实现中,返回结果是一个二维整数列表`List&lt;List&lt;Integer&gt;&gt; res`,其中每个子列表代表树的一层节点值。同样采用队列进行BFS,但每次...

    数据结构_ 二叉树

    而二叉树(Binary Tree)作为一种特殊的数据结构,是数据结构学习中的核心概念之一。二叉树是由n(n≥0)个有限节点组成的一个具有层次关系的集合,通常表示为一个由根节点、若干子树及叶子节点构成的分层结构。 ...

    商业编程-源码-严蔚敏:数据结构题集(C语言版)答案.zip

    5. **树**:分层数据结构,包括二叉树、平衡树(如AVL树和红黑树)、搜索树等。学习树的遍历算法和操作,如查找、插入和删除。 6. **图**:用于表示对象之间的关系,有邻接矩阵和邻接表两种表示方式。学习图的遍历...

    数据结构:第六章 树和二叉树.ppt

    数据结构中的树是一种非常重要的非线性数据结构,它由一系列结点(也称为节点)组成,这些结点通过边相互连接,形成一种分层结构。在树中,每个结点可以有零个或多个子结点,除了根结点之外,每个结点都有且仅有一个...

    二叉树抽象数据类型数据结构实验报告.doc

    例如,遍历二叉树可以采用前序遍历(根-左-右)、中序遍历(左-根-右)和后序遍历(左-右-根)等策略。遍历可以帮助我们访问和处理二叉树中的每一个节点。 **五、评估标准** 实验报告的质量将根据以下几个方面进行...

    二叉树及其运算.docx

    2. **分层打印二叉树**:这个任务要求按层次顺序打印二叉树的所有节点。首先将根节点放入队列,然后每次从队列中取出一个节点,打印其值,接着将其子节点(如果存在)添加到队列末尾。每层节点打印完毕后,打印一层...

    数据结构对二叉树的操作包括多二叉树的排序,建立,删除

    每个子树同样也是一颗二叉树,这种分层结构使得二叉树特别适合用来表示具有两种状态或关系的数据。 接下来,我们详细讨论二叉树的三个主要操作: 1. **建立二叉树**:构建二叉树通常从一组元素开始,例如数组或...

Global site tag (gtag.js) - Google Analytics