二叉树的宽度优先遍历
宽度优先遍历根据维基百科的解释如下:
广度优先搜索算法(英语:Breadth-First Search,缩写为BFS),又译作宽度优先搜索,或横向优先搜索,是一种图形搜索算法。简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。广度优先搜索的实现一般采用open-closed表。
对于一棵二叉树进行宽度优先遍历,可以采用队列的方式进行,即先进先出。具体思路如下:
先将根节点入队列,弹出根节点并且将其孩子入队列(左孩子先入队列)。
过程示意图如下:
代码实现如下:
//宽度遍历二叉树
class Node {
constructor({leftChild, rightChild, value}) {
this.leftChild = leftChild || null;
this.rightChild = rightChild || null;
this.value = value;
}
}
let node7 = new Node({leftChild: null, rightChild: null, value: 7});
let node6 = new Node({leftChild: null, rightChild: null, value: 6});
let node5 = new Node({leftChild: null, rightChild: null, value: 5});
let node4 = new Node({leftChild: null, rightChild: null, value: 4});
let node3 = new Node({leftChild: node6, rightChild: node7, value: 3});
let node2 = new Node({leftChild: node4, rightChild: node5, value: 2});
let node1 = new Node({leftChild: node2, rightChild: node3, value: 1});
function bfs(tree) {
if (tree === null) return [];
let Queque = [];
Queque.push(tree);
let printArray = [];
while(Queque.length > 0) {
let node = Queque.shift();
printArray.push(node.value);
node.leftChild&&Queque.push(node.leftChild);
node.rightChild&&Queque.push(node.rightChild);
}
return printArray;
}
console.log(bfs(node1)); //[ 1, 2, 3, 4, 5, 6, 7 ]
求一棵二叉树的宽度
在广度优先遍历的前提下,建立一种规则。该规则明确了遍历的节点是该层的第几个 count、该层的最后一个节点是哪个 currentEnd、下一层最后一个节点是哪个nextEnd、遍历到一层时,从节点到该层上一层的最大宽度 maxCount。
当遍历到的节点等于 currentEnd 时,表示该层遍历已经结束,重置变量,比较 count 与 maxCount,开始下一层的遍历。
流程图如下:
过程示意图如下:
代码实现
//二叉树的最大宽度
class Node {
constructor({leftChild, rightChild, value}) {
this.leftChild = leftChild || null;
this.rightChild = rightChild || null;
this.value = value;
}
}
let node8 = new Node({leftChild: null, rightChild: null, value: 8});
let node7 = new Node({leftChild: null, rightChild: null, value: 7});
let node6 = new Node({leftChild: null, rightChild: null, value: 6});
let node5 = new Node({leftChild: null, rightChild: null, value: 5});
let node4 = new Node({leftChild: node5, rightChild: node6, value: 4});
let node3 = new Node({leftChild: node8, rightChild: node7, value: 3});
let node2 = new Node({leftChild: node4, rightChild: null, value: 2});
let node1 = new Node({leftChild: node2, rightChild: node3, value: 1});
function maxBreadth (tree) {
if (tree === null ) {
return 0;
}
let queue = [tree];
let currentEnd = tree;
let nextEnd = tree;
let count = 0;
let maxCount = 0;
while (queue.length > 0) {
count++;
let el = queue.shift();
if (el.leftChild) {
queue.push(el.leftChild);
nextEnd = el.leftChild;
}
if (el.rightChild) {
queue.push(el.rightChild);
nextEnd = el.rightChild;
}
if (el === currentEnd) {
maxCount = maxCount >= count ? maxCount : count;
currentEnd = nextEnd;
nextEnd = null;
count = 0;
}
}
return maxCount;
}
console.log(maxBreadth (node1))//3
判断一棵二叉树是否是搜索二叉树
搜索二叉树根据维基百科的解释如下:
二叉查找树(英语:Binary Search Tree),也称为二叉查找树、有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
- 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
- 任意节点的左、右子树也分别为二叉查找树;
也就是说对于一棵二叉树来说,其中序遍历的结果是升序。所以,可以打印其中序遍历结果,查看其是否时升序。
判断一棵二叉树是完全二叉树
完全二叉树根据维基百科的解释如下:
在一颗二叉树中,若除最后一层外的其余层都是满的,并且最后一层要么是满的,要么在右边缺少连续若干节点,则此二叉树为完全二叉树(Complete Binary Tree)。
也就是说,用数组表示该二叉树的话,该数组必须是连续的,不允许中间有值不存在。
判断方式:当满足条件 1 后,不满足条件 2,则不是完全二叉树。
- 节点 node 左右孩子不同时存在;即节点 node 可能只有左孩子或者右孩子或者没有孩子。
- 节点 node 后的节点都必须是叶节点;也就是说节点 node 后面的节点都不能有孩子。
判断一棵二叉树是满二叉树
一棵深度为k,且有 个节点的二叉树,称为完美二叉树(Perfect Binary Tree)。这种树的特点是每一层上的节点数都是最大节点数。
也就是说是否是满二叉树,需要获取二叉树的高度 k 以及节点个数 n。只要满足 ,则是满二叉树。
//判断是否是满二叉树
class Node {
constructor({leftChild, rightChild, value}) {
this.leftChild = leftChild || null;
this.rightChild = rightChild || null;
this.value = value;
}
}
let node7 = new Node({leftChild: null, rightChild: null, value: 7});
let node6 = new Node({leftChild: null, rightChild: null, value: 6});
let node5 = new Node({leftChild: null, rightChild: null, value: 5});
let node4 = new Node({leftChild: null, rightChild: null, value: 4});
let node3 = new Node({leftChild: node6, rightChild: node7, value: 3});
let node2 = new Node({leftChild: node4, rightChild: node5, value: 2});
let node1 = new Node({leftChild: node2, rightChild: node3, value: 1});
function getData(node) {
if (node === null) return {
height: 0,
number: 0,
isBalance: true
};
let {height: leftHeight, isBalance: isLeftBalance, number: leftNumber} = getData(node.leftChild);
let {height: rightHeight, isBalance: isRigthBalance, number: rightNumber} = getData(node.rightChild);
return {
height: Math.max(leftHeight + 1, rightHeight + 1),
isBalance: isLeftBalance&&isRigthBalance&&(Math.abs(leftHeight - rightHeight) <= 1),
number: leftNumber + rightNumber + 1
}
}
const data = getData(node1);
console.log(isFull(data))
function isFull(data) {
return Math.pow(2, data.height) - 1 === data.number;
}
判断一棵二叉树是否是平衡二叉树
平衡二叉搜索树(英语:Balanced Binary Search Tree)是一种结构平衡的二叉搜索树,它是一种每个节点的左右两子树高度差都不超过一的二叉树。它能在 内完成插入、查找和删除操作,最早被发明的平衡二叉搜索树为AVL树。
判断是否是平衡二叉树的关键是对于每一个节点,它的左右两树的高度差不超过 1。可以使用递归的方式求解。
代码实现
//判断是否是平衡二叉树
class Node {
constructor({leftChild, rightChild, value}) {
this.leftChild = leftChild || null;
this.rightChild = rightChild || null;
this.value = value;
}
}
let node7 = new Node({leftChild: null, rightChild: null, value: 7});
let node6 = new Node({leftChild: null, rightChild: null, value: 6});
let node5 = new Node({leftChild: null, rightChild: null, value: 5});
let node4 = new Node({leftChild: null, rightChild: null, value: 4});
let node3 = new Node({leftChild: node6, rightChild: node7, value: 3});
let node2 = new Node({leftChild: node4, rightChild: node5, value: 2});
let node1 = new Node({leftChild: node2, rightChild: node3, value: 1});
function getData(node) {
if (node === null) return {
height: 0,
number: 0,
isBalance: true
};
let {height: leftHeight, isBalance: isLeftBalance, number: leftNumber} = getData(node.leftChild);
let {height: rightHeight, isBalance: isRigthBalance, number: rightNumber} = getData(node.rightChild);
return {
height: Math.max(leftHeight + 1, rightHeight + 1),
isBalance: isLeftBalance&&isRigthBalance&&(Math.abs(leftHeight - rightHeight) <= 1),
number: leftNumber + rightNumber + 1
}
}
const data = getData(node1);
console.log(data);
console.log(isBalanceTree(data));