看我的这个代码的话,你得先理解二叉树的宽度遍历是怎么做的,如果没有这个基础的话,先移步这里:宽度优先遍历在最后面哦
我在这里写了两种方法实现宽度优先遍历,一种使用了hashmap,第二种没有使用,节省了空间。直接上代码吧,注释很清楚了。
/**
* @author zrulin
* @create 2022-04-02 10:05
*/
public class 求二叉树的最大宽度 {
//基于队列,基于宽度优先遍历
public static void widthTraversal(Node head){
if(head != null){
Queue<Node> queue = new LinkedList<>();
queue.add(head);
Map<Node,Integer> leverMap = new HashMap<>();//用来记录节点所在的层数
leverMap.put(head,1);//头节点在第一层
int curLever = 1;//记录当前在第几层记录节点数
int curLeverNodes = 0;//记录当前层的节点数
int max = Integer.MIN_VALUE;//记录最大宽度,初始值为最小值。
while(!queue.isEmpty()){
head = queue.poll();
int curNodeLever = leverMap.get(head);//记录下当前在第几层
if(curLever == curNodeLever){//当前在记录的层数 和 当前的层数 是否相等
curLeverNodes++; //相等就记录下来,节点数加1
}else{
max = Math.max(max,curLeverNodes);//如果不相等就结算,
curLever = curNodeLever; //并且设置新的记录的层数和节点数
curLeverNodes = 1;
}
if(head.left != null) {
queue.add(head.left);
leverMap.put(head.left,curNodeLever+1);
}
if(head.right != null) {
queue.add(head.right);
leverMap.put(head.right,curNodeLever+1);
}
}
max = Math.max(max,curLeverNodes);//做最后一层的结算。
}
}
//不用map求二叉树最大宽度
public static void widthTraversal1(Node head){
if(head != null){
Queue<Node> queue = new LinkedList<>();
queue.add(head);
Node curEnd = head;
Node nextEnd = null;
int curLevelNodes = 0;
int max = Integer.MIN_VALUE;
while(!queue.isEmpty()){
Node cur = queue.poll();
if(cur.left != null) {
queue.add(cur.left);
nextEnd = cur.left;
}
if(head.right != null) {
queue.add(cur.right);
nextEnd = cur.right;
}
curLevelNodes++;
if(curEnd == cur){
curEnd = nextEnd;
nextEnd = null;
max = Math.max(max,curLevelNodes);
}
}
}
}
}
第二种方法也是看视频自己写的。
如果你想理解我写的第二种方法的话直接看这个左神的视频吧:左神讲算法(建议把时间直接定位到:2:09:15)
也非常推荐你看这个使用Java花样解决leetcode102.二叉树的层序遍历在实例中理解宽度遍历。去练练手吧。