按层次生成、遍历二叉树

对于二叉树一般是按深度生成和遍历,比如使用递归方法进行先序遍历、中序遍历、后序遍历。这次我们按层次生成和遍历二叉树。

这种遍历方式关键在于需要使用一个队列保存“已处理该节点,但还没处理它的子节点”这样的节点。

# Python代码

# Definition for singly-linked list.
class BinTree(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution(object):

    # 按层次建立二叉树
    def createBinTree(self, inputList):

        # 尚未设置子节点的节点列表
        nodeList = []

        if (inputList == None) or (len(inputList) == 0):
            return None
        # 取出根元素
        value = inputList.pop(0)
        root = BinTree(value)
        nodeList.append(root)

        # 结束条件:所有值不为“#”的节点都设置了子节点,即nodeList为空
        while len(nodeList) != 0:
            leftValue = inputList.pop(0)
            rightValue = inputList.pop(0)
            if leftValue != '#' and rightValue != '#':
                nodeLeft = BinTree(leftValue)
                nodeRight = BinTree(rightValue)

                # 每次取出两个节点,加入到 “未设置子节点的节点列表”
                nodeList.append(nodeLeft)
                nodeList.append(nodeRight)
                nodeList[0].left = nodeLeft
                nodeList[0].right = nodeRight

                # 为节点设置子节点后移出队列
                nodeList.pop(0)

            # 若值为#,不需要处理,默认情况下节点的左右节点都为None
            elif leftValue == '#' and rightValue != '#':
                nodeRight = BinTree(rightValue)
                nodeList.append(nodeRight)
                nodeList[0].right = nodeRight
                nodeList.pop(0)
            elif rightValue == '#' and leftValue != '#':
                nodeLeft = BinTree(leftValue)
                nodeList.append(nodeLeft)
                nodeList[0].left = nodeLeft
                nodeList.pop(0)
            else:
                nodeList.pop(0)
        return root

    # 按层次遍历二叉树
    def traverseBinTree(self, root):
        nodeList = []

        # 先将根节点加入队列中
        if root != None:
            nodeList.append(root)
        while len(nodeList) != 0:

            # 输出队列第一个节点值,并将该节点的左右子节点加入队列
            node = nodeList.pop(0)
            if node == None:
                print('#')
                continue
            print(node.val)

            leftNode = node.left
            rightNode = node.right

            nodeList.append(leftNode)
            nodeList.append(rightNode)



s = Solution()
root = s.createBinTree(inputList = ['A', 'B', 'C', '#', 'D', '#', 'E', 'F', '#', '#', '#', '#', '#'])
s.traverseBinTree(root)

再进一步,不仅要按层次遍历二叉树,还要将每一层分别放在一个列表中。[ [3], [9,20], [15,7] ],实现这个要求重点在于确定何时一层遍历完成。每层二叉树的节点数目(含null节点)为上一层不含null节点的数目 * 2。可以采用两个变量,记录本层应该有多少个节点、和已经遍历到多少个节点。二者相等时,本层节点遍历结束。

// Java代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> resultList = new ArrayList<>();

        // 记录待遍历的节点,每次取出队首元素,并将其子节点(如果有)添加到队列中。
        // 当nodeList为空时,所有节点遍历结束
        List<TreeNode> nodeList = new ArrayList<>();

        // 记录二叉树每一层的节点
        List<Integer> layerList = new ArrayList<>();

        // 本层应该有多少个节点
        int eachLineNodeNum = 1;

        // 已经遍历到多少个节点
        int currentNodeNum = 0;

        // 本层有多少个空节点
        int nullNodeNum = 0;

        if (root != null)
            nodeList.add(root);
        while (nodeList.size() != 0) {
            TreeNode node = nodeList.remove(0);
            if (node == null) {
                nullNodeNum ++;

                currentNodeNum++;

                if (eachLineNodeNum == currentNodeNum) {

                    // 下一层的节点数应为本层非空节点数 *2
                    eachLineNodeNum = (eachLineNodeNum - nullNodeNum) * 2;
                    currentNodeNum = 0;
                    nullNodeNum = 0;
// System.out.println("一层结束");

                    // 将layerList复制一份。
                    // 否则由于"引用传递"的特点,执行layerList.clear()时也会将resultList中的结果清除
                    if (layerList.size() != 0) {
                        resultList.add(new ArrayList<Integer>(layerList));
                        layerList.clear();
                    }

                }
                continue;
            }
            layerList.add(node.val);
            currentNodeNum++;
            if (eachLineNodeNum == currentNodeNum) {
                eachLineNodeNum = (eachLineNodeNum - nullNodeNum) * 2;
                currentNodeNum = 0;
                nullNodeNum = 0;
// System.out.println("一层结束");
                if (layerList.size() != 0) {
                    resultList.add(new ArrayList<Integer>(layerList));
                    layerList.clear();
                }
            }

            TreeNode leftNode = node.left;
            TreeNode rightNode = node.right;

            nodeList.add(leftNode);
            nodeList.add(rightNode);
        }

        Collections.reverse(resultList);
        return resultList;
    }
}
    原文作者:满二叉树
    原文地址: https://blog.csdn.net/u013632190/article/details/52148633
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞