2018-10-10 18:03:03 -04:00
|
|
|
---
|
|
|
|
id: 587d8258367417b2b2512c7f
|
2020-12-16 00:37:30 -07:00
|
|
|
title: 在二叉搜索树中使用广度优先搜索
|
2018-10-10 18:03:03 -04:00
|
|
|
challengeType: 1
|
|
|
|
videoUrl: ''
|
2021-01-13 03:31:00 +01:00
|
|
|
dashedName: use-breadth-first-search-in-a-binary-search-tree
|
2018-10-10 18:03:03 -04:00
|
|
|
---
|
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
# --description--
|
2018-10-10 18:03:03 -04:00
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
这里我们将介绍另一种树遍历方法:广度优先搜索。与上一次挑战中的深度优先搜索方法相比,广度优先搜索在继续进入下一级别之前探索树中给定级别中的所有节点。通常,队列在广度优先搜索算法的设计中用作辅助数据结构。在此方法中,我们首先将根节点添加到队列中。然后我们开始一个循环,我们将队列中的第一个项目出列,将其添加到一个新数组,然后检查它们的子子树。如果它的孩子不是空的,他们每个都被排队。此过程将继续,直到队列为空。说明:让我们在树中创建一个名为`levelOrder`的广度优先搜索方法。此方法应返回一个包含所有树节点值的数组,并以广度优先的方式进行探索。确保返回数组中的值,而不是节点本身。应从左到右遍历一个级别。接下来,让我们编写一个名为`reverseLevelOrder`的类似方法,它在每个级别执行相同的搜索,但是反向(从右到左)。
|
2018-10-10 18:03:03 -04:00
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
# --hints--
|
2018-10-10 18:03:03 -04:00
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
存在`BinarySearchTree`数据结构。
|
2018-10-10 18:03:03 -04:00
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
```js
|
|
|
|
assert(
|
|
|
|
(function () {
|
|
|
|
var test = false;
|
|
|
|
if (typeof BinarySearchTree !== 'undefined') {
|
|
|
|
test = new BinarySearchTree();
|
|
|
|
}
|
|
|
|
return typeof test == 'object';
|
|
|
|
})()
|
|
|
|
);
|
|
|
|
```
|
|
|
|
|
|
|
|
二叉搜索树有一个名为`levelOrder`的方法。
|
2018-10-10 18:03:03 -04:00
|
|
|
|
|
|
|
```js
|
2020-12-16 00:37:30 -07:00
|
|
|
assert(
|
|
|
|
(function () {
|
|
|
|
var test = false;
|
|
|
|
if (typeof BinarySearchTree !== 'undefined') {
|
|
|
|
test = new BinarySearchTree();
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return typeof test.levelOrder == 'function';
|
|
|
|
})()
|
|
|
|
);
|
|
|
|
```
|
2018-10-10 18:03:03 -04:00
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
二叉搜索树有一个名为`reverseLevelOrder`的方法。
|
|
|
|
|
|
|
|
```js
|
|
|
|
assert(
|
|
|
|
(function () {
|
|
|
|
var test = false;
|
|
|
|
if (typeof BinarySearchTree !== 'undefined') {
|
|
|
|
test = new BinarySearchTree();
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return typeof test.reverseLevelOrder == 'function';
|
|
|
|
})()
|
|
|
|
);
|
2018-10-10 18:03:03 -04:00
|
|
|
```
|
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
`levelOrder`方法返回按级别顺序探索的树节点值的数组。
|
2018-10-10 18:03:03 -04:00
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
```js
|
|
|
|
assert(
|
|
|
|
(function () {
|
|
|
|
var test = false;
|
|
|
|
if (typeof BinarySearchTree !== 'undefined') {
|
|
|
|
test = new BinarySearchTree();
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (typeof test.levelOrder !== 'function') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
test.add(7);
|
|
|
|
test.add(1);
|
|
|
|
test.add(9);
|
|
|
|
test.add(0);
|
|
|
|
test.add(3);
|
|
|
|
test.add(8);
|
|
|
|
test.add(10);
|
|
|
|
test.add(2);
|
|
|
|
test.add(5);
|
|
|
|
test.add(4);
|
|
|
|
test.add(6);
|
|
|
|
return test.levelOrder().join('') == '719038102546';
|
|
|
|
})()
|
|
|
|
);
|
|
|
|
```
|
2018-10-10 18:03:03 -04:00
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
`reverseLevelOrder`方法返回以反向级别顺序探索的树节点值的数组。
|
2018-10-10 18:03:03 -04:00
|
|
|
|
|
|
|
```js
|
2020-12-16 00:37:30 -07:00
|
|
|
assert(
|
|
|
|
(function () {
|
|
|
|
var test = false;
|
|
|
|
if (typeof BinarySearchTree !== 'undefined') {
|
|
|
|
test = new BinarySearchTree();
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (typeof test.reverseLevelOrder !== 'function') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
test.add(7);
|
|
|
|
test.add(1);
|
|
|
|
test.add(9);
|
|
|
|
test.add(0);
|
|
|
|
test.add(3);
|
|
|
|
test.add(8);
|
|
|
|
test.add(10);
|
|
|
|
test.add(2);
|
|
|
|
test.add(5);
|
|
|
|
test.add(4);
|
|
|
|
test.add(6);
|
|
|
|
return test.reverseLevelOrder().join('') == '791108305264';
|
|
|
|
})()
|
|
|
|
);
|
2018-10-10 18:03:03 -04:00
|
|
|
```
|
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
`levelOrder`方法为空树返回`null` 。
|
2018-10-10 18:03:03 -04:00
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
```js
|
|
|
|
assert(
|
|
|
|
(function () {
|
|
|
|
var test = false;
|
|
|
|
if (typeof BinarySearchTree !== 'undefined') {
|
|
|
|
test = new BinarySearchTree();
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (typeof test.levelOrder !== 'function') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return test.levelOrder() == null;
|
|
|
|
})()
|
|
|
|
);
|
|
|
|
```
|
2018-10-10 18:03:03 -04:00
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
`reverseLevelOrder`方法为空树返回`null` 。
|
2018-10-10 18:03:03 -04:00
|
|
|
|
|
|
|
```js
|
2020-12-16 00:37:30 -07:00
|
|
|
assert(
|
|
|
|
(function () {
|
|
|
|
var test = false;
|
|
|
|
if (typeof BinarySearchTree !== 'undefined') {
|
|
|
|
test = new BinarySearchTree();
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (typeof test.reverseLevelOrder !== 'function') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return test.reverseLevelOrder() == null;
|
|
|
|
})()
|
|
|
|
);
|
2018-10-10 18:03:03 -04:00
|
|
|
```
|
2020-08-13 17:24:35 +02:00
|
|
|
|
2021-01-13 03:31:00 +01:00
|
|
|
# --seed--
|
|
|
|
|
|
|
|
## --after-user-code--
|
|
|
|
|
|
|
|
```js
|
|
|
|
BinarySearchTree.prototype = Object.assign(
|
|
|
|
BinarySearchTree.prototype,
|
|
|
|
{
|
|
|
|
add: function(value) {
|
|
|
|
function searchTree(node) {
|
|
|
|
if (value < node.value) {
|
|
|
|
if (node.left == null) {
|
|
|
|
node.left = new Node(value);
|
|
|
|
return;
|
|
|
|
} else if (node.left != null) {
|
|
|
|
return searchTree(node.left);
|
|
|
|
}
|
|
|
|
} else if (value > node.value) {
|
|
|
|
if (node.right == null) {
|
|
|
|
node.right = new Node(value);
|
|
|
|
return;
|
|
|
|
} else if (node.right != null) {
|
|
|
|
return searchTree(node.right);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var node = this.root;
|
|
|
|
if (node == null) {
|
|
|
|
this.root = new Node(value);
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
return searchTree(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
```
|
|
|
|
|
|
|
|
## --seed-contents--
|
|
|
|
|
|
|
|
```js
|
|
|
|
var displayTree = tree => console.log(JSON.stringify(tree, null, 2));
|
|
|
|
function Node(value) {
|
|
|
|
this.value = value;
|
|
|
|
this.left = null;
|
|
|
|
this.right = null;
|
|
|
|
}
|
|
|
|
function BinarySearchTree() {
|
|
|
|
this.root = null;
|
|
|
|
// Only change code below this line
|
|
|
|
|
|
|
|
// Only change code above this line
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2020-12-16 00:37:30 -07:00
|
|
|
# --solutions--
|
|
|
|
|
2021-01-13 03:31:00 +01:00
|
|
|
```js
|
|
|
|
var displayTree = tree => console.log(JSON.stringify(tree, null, 2));
|
|
|
|
function Node(value) {
|
|
|
|
this.value = value;
|
|
|
|
this.left = null;
|
|
|
|
this.right = null;
|
|
|
|
}
|
|
|
|
function BinarySearchTree() {
|
|
|
|
this.root = null;
|
|
|
|
// Only change code below this line
|
|
|
|
this.levelOrder = (root = this.root) => {
|
|
|
|
if(!root) return null;
|
|
|
|
let queue = [root];
|
|
|
|
let results = [];
|
|
|
|
while(queue.length > 0) {
|
|
|
|
let node = queue.shift();
|
|
|
|
results.push(node.value);
|
|
|
|
if(node.left) queue.push(node.left);
|
|
|
|
if(node.right) queue.push(node.right);
|
|
|
|
}
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.reverseLevelOrder = (root = this.root) => {
|
|
|
|
if(!root) return null;
|
|
|
|
let queue = [root];
|
|
|
|
let results = [] ;
|
|
|
|
while ( queue.length > 0) {
|
|
|
|
let node = queue.shift();
|
|
|
|
results.push(node.value);
|
|
|
|
if(node.right) queue.push(node.right);
|
|
|
|
if(node.left ) queue.push(node.left);
|
|
|
|
}
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
// Only change code above this line
|
|
|
|
}
|
|
|
|
```
|