freeCodeCamp/curriculum/challenges/chinese/10-coding-interview-prep/data-structures/use-depth-first-search-in-a...

325 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
id: 587d8257367417b2b2512c7e
title: 在二叉搜索树中使用深度优先搜索
challengeType: 1
videoUrl: ''
dashedName: use-depth-first-search-in-a-binary-search-tree
---
# --description--
我们知道如何在二叉搜索树中搜索特定值。但是如果我们只想探索整棵树呢或者如果我们没有有序树我们只需要搜索一个值这里我们将介绍一些可用于探索树数据结构的树遍历方法。首先是深度优先搜索。在深度优先搜索中在搜索继续到另一个子树之前尽可能深地探索给定子树。有三种方法可以完成按顺序从最左边的节点开始搜索到最右边的节点结束。预购在树叶前探索所有的根。下订单在根之前探索所有的叶子。您可能会猜到您可以选择不同的搜索方法具体取决于树存储的数据类型以及您要查找的内容。对于二叉搜索树inorder遍历以排序顺序返回节点。说明这里我们将在二叉搜索树上创建这三种搜索方法。深度优先搜索是一种固有的递归操作只要子节点存在它就会继续探索更多的子树。一旦理解了这个基本概念您就可以简单地重新排列探索节点和子树的顺序以生成上述三个搜索中的任何一个。例如在后序搜索中我们希望在开始返回任何节点本身之前一直递归到叶节点而在预订搜索中我们希望首先返回节点然后继续递归在树下。在我们的树上定义`inorder` `preorder`和`postorder`方法。这些方法中的每一个都应该返回表示树遍历的项数组。确保返回数组中每个节点的整数值,而不是节点本身。最后,如果树为空,则返回`null` 。
# --hints--
存在`BinarySearchTree`数据结构。
```js
assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
}
return typeof test == 'object';
})()
);
```
二叉搜索树有一个名为`inorder`的方法。
```js
assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
return typeof test.inorder == 'function';
})()
);
```
二叉搜索树有一个名为`preorder`的方法。
```js
assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
return typeof test.preorder == 'function';
})()
);
```
二叉搜索树有一个名为`postorder`的方法。
```js
assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
return typeof test.postorder == 'function';
})()
);
```
`inorder`方法返回由inorder遍历产生的节点值数组。
```js
assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
if (typeof test.inorder !== '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.inorder().join('') == '012345678910';
})()
);
```
`preorder`方法返回由前序遍历产生的节点值数组。
```js
assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
if (typeof test.preorder !== '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.preorder().join('') == '710325469810';
})()
);
```
`postorder`方法返回由后序遍历产生的节点值数组。
```js
assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
if (typeof test.postorder !== '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.postorder().join('') == '024653181097';
})()
);
```
`inorder`方法为空树返回`null` 。
```js
assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
if (typeof test.inorder !== 'function') {
return false;
}
return test.inorder() == null;
})()
);
```
`preorder`方法为空树返回`null` 。
```js
assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
if (typeof test.preorder !== 'function') {
return false;
}
return test.preorder() == null;
})()
);
```
`postorder`方法为空树返回`null` 。
```js
assert(
(function () {
var test = false;
if (typeof BinarySearchTree !== 'undefined') {
test = new BinarySearchTree();
} else {
return false;
}
if (typeof test.postorder !== 'function') {
return false;
}
return test.postorder() == null;
})()
);
```
# --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
}
```
# --solutions--
```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;
this.result = [];
this.inorder = function(node) {
if (!node) node = this.root;
if (!node) return null;
if (node.left) this.inorder(node.left);
this.result.push(node.value);
if (node.right) this.inorder(node.right);
return this.result;
};
this.preorder = function(node) {
if (!node) node = this.root;
if (!node) return null;
this.result.push(node.value);
if (node.left) this.preorder(node.left);
if (node.right) this.preorder(node.right);
return this.result;
};
this.postorder = function(node) {
if (!node) node = this.root;
if (!node) return null;
if (node.left) this.postorder(node.left);
if (node.right) this.postorder(node.right);
this.result.push(node.value);
return this.result;
};
}
```