ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二叉树所有层中最多的节点个数和最大宽度

2021-04-08 17:59:00  阅读:231  来源: 互联网

标签:node Node deque int 层中 队列 二叉树 节点


求二叉树所有层中最多的节点个数

解题思路:根据题意可知,要想获得二叉树中每一层的节点个数,需要对二叉树进行层序遍历,并在层序遍历的过程中记录每一层具有多少个节点。因此可以在层序遍历每一个节点的时候为每个节点分配一个层数的记录。层序遍历的方法通常是使用队列进行,首先将头节点加入到队列中,如果头节点不为空,将队列中的第一个元素弹出,这个被弹出的元素的左子节点不为空则将左子节点加入到队列中;如果右节点不为空则将右子节点加入到队列中。但是层序遍历的过程中并没有统计每一个节点到底属于哪一层的信息,因此需要将节点与节点所属层数信息进行绑定。这里可以借用一个辅助类构造一个辅助节点,将节点和节点所属层数作为成员变量。每次入队列和出队列的时候直接对这个辅助节点进行操作即可。判断该节点所在的层数和当前层数是否相同,如果相同则将该层的个数进行加1,如果不同,则将该层的节点个数设置为0,当前层加1,进行重新计数。
代码如下:

public static int getMaxNumOfNodes(Node root) {
    if (root == null) {
        return 0;
    }
    Queue<AnotateNode> queue = new LinkedList<>();
    // 将头节点加入到队列中
    queue.offer(new AnotateNode(root, 1));
    // 当前节点层数
    int curLevel = 1;
    // 当前层的节点个数
    int numNodes = 0;
    // 由于头节点不为空,所以最大节点个数至少为1
    int maxNodes = 1;
    while (!queue.isEmpty()) {
        AnotateNode aNode = queue.poll();
        int nodeLevel = aNode.levels;
        if (curLevel == nodeLevel) {
            numNodes++;
        } else {
        	// 新的一层开始,更新前一层的最大节点数信息
            maxNodes = Math.max(maxNodes, numNodes);
            curLevel = nodeLevel;
            numNodes = 1;
        }
        if (aNode.node.left != null) {
            queue.offer(new AnotateNode(aNode.node.left, aNode.levels + 1));
        }

        if (aNode.node.right != null) {
            queue.offer(new AnotateNode(aNode.node.right, aNode.levels + 1));
        }
    }
    maxNodes = Math.max(numNodes, maxNodes);
    return maxNodes;
}


class Node {
    int value;
    Node left;
    Node right;
    public Node(int value) {
        this.value = value;
    }
}

class AnotateNode {
    int levels;
    Node node;
    public AnotateNode(Node node, int levels) {
        this.levels = levels;
        this.node = node;
    }
}

求二叉树的最大宽度(leetcode 662)

解题思路:也是按照层序遍历的思路,与求所有层最多节点个数不同的是,当第三层的节点为[v1,v2,null,v4]时,最多节点个数是3,而最大宽度是4。因此可以使用双端队列的方式,为每一个节点构造一个辅助节点,将节点与节点在当前层的位置绑定在一起,因此在每次入栈或者出栈的过程中,就获得了当前节点的位置信息。由于使用的是双端队列,因此可以通过队列头和队列尾获得当前层的最大宽度。那么如何统计下一层的位置信息呢,这里采用左子节点是父节点的位置的2倍,即(2 * postion);左子节点是父节点的2别+1,即(2 * position + 1)。当左右节点不为空的时候将节点和其位置信息加入。当每一层节点遍历结束时,更新最大宽度。
代码如下:

public static int maxWidth(Node root) {
    if (root == null) {
        return 0;
    }
    // 创建双端队列
    Deque<AuxiliaryNode> deque = new LinkedList<>();
    // 将头节点加入
    deque.offer(new AuxiliaryNode(root, 0));
    
    int maxWidth = 0;
    while (!deque.isEmpty()) {
    maxWidth = Math.max(maxWidth, deque.peekLast().position - deque.peekFirst().position + 1);
        int size = deque.size();
        while (size > 0) {
        
            AuxiliaryNode curANode = deque.poll();
            Node curNode = curANode.node;
            int curPosition = curANode.position;

            if (curNode.left != null) {
                deque.offer(new AuxiliaryNode(curNode.left, 2 * curPosition));
            }

            if (curNode.right != null) {
                deque.offer(new AuxiliaryNode(curNode.right, 2 * curPosition + 1));
            }
            
            size--;
        }
    }
    return maxWidth;

}

class Node {
    int value;
    Node left;
    Node right;
    public Node(int value) {
        this.value = value;
    }
}

class AuxiliaryNode {
    int position;
    Node node;
    public AuxiliaryNode(Node node, int position) {
        this.node = node;
        this.position = position;
    }
}

标签:node,Node,deque,int,层中,队列,二叉树,节点
来源: https://blog.csdn.net/qq_38756539/article/details/115522870

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有