题目
求一个二叉树的最大宽度
- 因为要求宽度,所以遍历方式选择宽度遍历,但是只是宽度遍历,无法知道当前节点的层级,便无法统计每层有多少个节点
- 设置当前节点层级:从第一个节点开始,第一个节点的层级为1,当宽度遍历,往队列中放当前节点的左右子节点时,设置左右节点层级为当前节点层级+1
- 因为是宽度遍历,当遍历到第一层时,放置到第二层的节点层级都已知晓,遍历第二层,放置第三层的节点层级都已知晓
- 获取当前节点层级:在设置层级时,通过map来进行每个节点的层级映射,后续根据当前遍历的节点就能取出节点的层级,然后后进行统计高度和每层数量的操作
function BFS(head) {
let arr = [];
arr.push(head);
//当前遍历到的层级
let level = 1;
//统计当前层的节点树
let currentLeveNodesNum = 0;
let max = 0;
//通过map来映射每个节点的层级
let map = new Map();
map.set(head, level);
for (let i = 0; i < head.length; i++) {
let currentNodeLevel = map.get(arr[i]);
//如果当前节点的层级和宽度优先遍历到的层级相同
if (currentNodeLevel === level) {
currentLeveNodesNum++;
} else {
//到了下一层
max = Math.max(max, currentLeveNodesNum);
level++;
currentLeveNodesNum = 1;
}
if (arr[i].left) {
//因为第一个节点知道自己的层级,所以它的子节点就是当前节点+1
//那之后的每个节点的层级,都可以通过它的上层节点来设置
map.set(arr[i].left, currentNodeLevel + 1);
arr.push(arr[i].left);
}
if (arr[i].right) {
map.set(arr[i].right, currentNodeLevel + 1);
arr.push(arr[i].right);
}
}
return [level,max]
}
不用map结构的方法
- 一定能够通过当前层的最后一个节点,知道下一层的最后一个节点,因为下一层最后一个节点是它的左节点或右节点
- 从第一个节点开始,一定知道第二层的最后一个节点,记录第二层的最后一个节点,当遍历到的节点,如果节点等于之前记录的第二层的最后一个节点,说明第二层遍历完了,进行统计宽度等操作,同时一定能够通过该节点知道第三层的最后一个节点,第三层同样进行这样的判断,之后类似。
function BFS2(head) {
let arr = [];
arr.push(head);
//当前遍历到的层级
let level = 1;
let currentLevelNodeNum = 0;
let max = 0;
let curentLevelEndNode = head;
let nextLevelEndNode = null;
//每次通过nextLevelEndNode记录下一层的最后一个子节点
//当本次遍历的节点==curentLevelEndNode即记录的最后一层节点时,进行最大宽度计算等统计
//因为当遍历到当前层的最后一个节点时,一定能够通过该节点知道下一层的最后一个节点
//所以curentLevelEndNode和nextLevelEndNode互换
for (let i = 0; i < head.length; i++) {
if (arr[i].left) {
nextLevelEndNode = arr[i].left;
arr.push(arr[i].left);
}
if (arr[i].right) {
nextLevelEndNode = arr[i].right;
arr.push(arr[i].right);
}
//遍历到了当前层的最后一个节点
//将最后一个节点的子节点(上方遍历时记录的)给curentLevelEndNode标志下一层的最后一个节点
if (arr[i] == curentLevelEndNode) {
curentLevelEndNode = nextLevelEndNode;
if (nextLevelEndNode != null) {
level++;
}
curentLevelEndNodeNUm++;
max = Math.max(max, currentLevelNodeNum);
currentLevelNodeNum = 0;
} else {
currentLevelNodeNum++;
}
}
return [level, max];
}