mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-02-28 14:01:32 -05:00
refactor(curriculum): improve binary search tree (#53622)
Co-authored-by: Dario-DC <dicillodario@gmail.com> Co-authored-by: Mama Naomi <nhcarrigan@gmail.com> Co-authored-by: Dario-DC <105294544+Dario-DC@users.noreply.github.com>
This commit is contained in:
@@ -12,248 +12,252 @@
|
||||
"isBeta": true,
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "65560f9380be92226084ef46",
|
||||
"id": "65c4eb814cc977c95cd7df0e",
|
||||
"title": "Step 1"
|
||||
},
|
||||
{
|
||||
"id": "65560ffdb7d05d248e012280",
|
||||
"id": "65c4ef8463f869d0eaf87c67",
|
||||
"title": "Step 2"
|
||||
},
|
||||
{
|
||||
"id": "65561022956c1024e7184add",
|
||||
"id": "65c4f013851cefd1a4fe4c96",
|
||||
"title": "Step 3"
|
||||
},
|
||||
{
|
||||
"id": "655a10e4a620fc091ba43b3d",
|
||||
"id": "65c4f02dbd3557d23f12db62",
|
||||
"title": "Step 4"
|
||||
},
|
||||
{
|
||||
"id": "655a1188d6cfbb0a3ec63c57",
|
||||
"id": "65c4f07da204f4d2f325fbd3",
|
||||
"title": "Step 5"
|
||||
},
|
||||
{
|
||||
"id": "655a11eb4e54b60acd6bd641",
|
||||
"id": "65c4f09e074dd8d37830ea00",
|
||||
"title": "Step 6"
|
||||
},
|
||||
{
|
||||
"id": "655a12c2ab0bcc0c2ba30e16",
|
||||
"id": "65c4f0b82db314d3fcc0b8e1",
|
||||
"title": "Step 7"
|
||||
},
|
||||
{
|
||||
"id": "655a132b56e0160cfeca08d4",
|
||||
"id": "65c4f0d32ca17ad4b1636b0e",
|
||||
"title": "Step 8"
|
||||
},
|
||||
{
|
||||
"id": "655a13744e82580d7ee3073d",
|
||||
"id": "65c4f195de7e2ad5932be717",
|
||||
"title": "Step 9"
|
||||
},
|
||||
{
|
||||
"id": "655a13aa8af2510de51f2e1c",
|
||||
"id": "65c4f22498d22ed775ef8efb",
|
||||
"title": "Step 10"
|
||||
},
|
||||
{
|
||||
"id": "655a142ae611b30e5df0ac16",
|
||||
"id": "65c4f2851645e8d84d14f5d1",
|
||||
"title": "Step 11"
|
||||
},
|
||||
{
|
||||
"id": "655a1479ba7e7c0ee6c1acdd",
|
||||
"id": "65c4f2b7178afed8e88f782f",
|
||||
"title": "Step 12"
|
||||
},
|
||||
{
|
||||
"id": "655a14a6fe4cd50f38d01dd3",
|
||||
"id": "65c4f2d9fd872fd99ac659dd",
|
||||
"title": "Step 13"
|
||||
},
|
||||
{
|
||||
"id": "655a151cc6041f0ff7d24ded",
|
||||
"id": "65c4f300da28d8da361bfa93",
|
||||
"title": "Step 14"
|
||||
},
|
||||
{
|
||||
"id": "655a153a6b362d103e125028",
|
||||
"id": "65c4f3258d2e4cdacc919dfd",
|
||||
"title": "Step 15"
|
||||
},
|
||||
{
|
||||
"id": "655a1564f3aa8210938cdf68",
|
||||
"id": "65c4f33bc3c3d8db7f732787",
|
||||
"title": "Step 16"
|
||||
},
|
||||
{
|
||||
"id": "655a158c7e80c810f6eff1e1",
|
||||
"id": "65c4f37ba6cbcfdc77e24165",
|
||||
"title": "Step 17"
|
||||
},
|
||||
{
|
||||
"id": "655a15b683445611528cccf1",
|
||||
"id": "65c4f3aee69d11dcfdbcfc00",
|
||||
"title": "Step 18"
|
||||
},
|
||||
{
|
||||
"id": "655a227e57aabb25d1f9c987",
|
||||
"id": "65c63a4c4da62e9ae18e321a",
|
||||
"title": "Step 19"
|
||||
},
|
||||
{
|
||||
"id": "655a167ea3e96512bf1343ce",
|
||||
"id": "65c63da2ed6769a10e141341",
|
||||
"title": "Step 20"
|
||||
},
|
||||
{
|
||||
"id": "655a16db1ccc5e132b5bc44d",
|
||||
"id": "65c63df529bd15a24c187c62",
|
||||
"title": "Step 21"
|
||||
},
|
||||
{
|
||||
"id": "655a173e5b8adc13b761ed74",
|
||||
"id": "65c63e6962159fa372ecdbec",
|
||||
"title": "Step 22"
|
||||
},
|
||||
{
|
||||
"id": "655a194276dfa11460f7b5e3",
|
||||
"id": "65c63eb01b9563a4b8a046b6",
|
||||
"title": "Step 23"
|
||||
},
|
||||
{
|
||||
"id": "655a1a6d8c44db154b00c909",
|
||||
"id": "65c63fd9b387f0a6c5bf6a72",
|
||||
"title": "Step 24"
|
||||
},
|
||||
{
|
||||
"id": "655a44442b60ee5a28df8ee5",
|
||||
"id": "65c64057a080baa7d60523ed",
|
||||
"title": "Step 25"
|
||||
},
|
||||
{
|
||||
"id": "655a452d40556e5c25e4aac8",
|
||||
"id": "65c6409418806da8d0636ffc",
|
||||
"title": "Step 26"
|
||||
},
|
||||
{
|
||||
"id": "655a45c52fa3ea5ece3034c7",
|
||||
"id": "65f97131a0709033d6911558",
|
||||
"title": "Step 27"
|
||||
},
|
||||
{
|
||||
"id": "655a4614304cd36031cb4e75",
|
||||
"id": "65c644829cfb63acf3479d09",
|
||||
"title": "Step 28"
|
||||
},
|
||||
{
|
||||
"id": "655a46aa8e10c26218c5034c",
|
||||
"id": "65c645b838e7deb080fc25e0",
|
||||
"title": "Step 29"
|
||||
},
|
||||
{
|
||||
"id": "655a46fce0ce5a638c180e36",
|
||||
"id": "65c646d4148ae3b2d1cbcac4",
|
||||
"title": "Step 30"
|
||||
},
|
||||
{
|
||||
"id": "655a4761e1a40065fc4d3712",
|
||||
"id": "65c9ddd336596e30a4266a50",
|
||||
"title": "Step 31"
|
||||
},
|
||||
{
|
||||
"id": "655a47a9404d856743c7f529",
|
||||
"id": "65c9de201959f73591b606e6",
|
||||
"title": "Step 32"
|
||||
},
|
||||
{
|
||||
"id": "655a482dfc92896901b9c97e",
|
||||
"id": "65ca03bd8eb5faf24b250c56",
|
||||
"title": "Step 33"
|
||||
},
|
||||
{
|
||||
"id": "655a489d83b1996bd537b153",
|
||||
"id": "65ca05f7cba1e6fe70527534",
|
||||
"title": "Step 34"
|
||||
},
|
||||
{
|
||||
"id": "655a48da2c25656d2f7bab4d",
|
||||
"id": "65ca06475e9b8aff8ea5a5f1",
|
||||
"title": "Step 35"
|
||||
},
|
||||
{
|
||||
"id": "655a493ab909a96f7c316cd5",
|
||||
"id": "65ca06864129380054b55dc0",
|
||||
"title": "Step 36"
|
||||
},
|
||||
{
|
||||
"id": "655a4ffc762d117470b94e3b",
|
||||
"id": "65ca06c9f918730107c9908d",
|
||||
"title": "Step 37"
|
||||
},
|
||||
{
|
||||
"id": "655a50f992ba7177aff2b718",
|
||||
"id": "65ca071d5921760254949f76",
|
||||
"title": "Step 38"
|
||||
},
|
||||
{
|
||||
"id": "655a515f4b85ce79464fe5e8",
|
||||
"id": "65ca075e3184180309f4c1d9",
|
||||
"title": "Step 39"
|
||||
},
|
||||
{
|
||||
"id": "655a51a705c97d7a9294ab2a",
|
||||
"id": "65ca0794ec3ed103bca67ed7",
|
||||
"title": "Step 40"
|
||||
},
|
||||
{
|
||||
"id": "655a51ff908edc7c12c3a92c",
|
||||
"id": "65ca07dd6fa8840491b7a5cd",
|
||||
"title": "Step 41"
|
||||
},
|
||||
{
|
||||
"id": "655a523d4bbc8b7d3848d7dd",
|
||||
"id": "65cb45d130c97cb459439fac",
|
||||
"title": "Step 42"
|
||||
},
|
||||
{
|
||||
"id": "655a52bca925967fa2336190",
|
||||
"id": "65ca085a19adaa057302a3d6",
|
||||
"title": "Step 43"
|
||||
},
|
||||
{
|
||||
"id": "655a536e99be288210f01451",
|
||||
"id": "65d8b58074495d3f94977dca",
|
||||
"title": "Step 44"
|
||||
},
|
||||
{
|
||||
"id": "655a5489c62889851c60ff4b",
|
||||
"id": "65ca089e848eca0672b9cd77",
|
||||
"title": "Step 45"
|
||||
},
|
||||
{
|
||||
"id": "655a54cd88e33b8646c67e16",
|
||||
"id": "65d8a6fcb15a3a239ba35dfd",
|
||||
"title": "Step 46"
|
||||
},
|
||||
{
|
||||
"id": "655a54fd97ada88722fa5c8b",
|
||||
"id": "65d8a8773c816a273653fd0e",
|
||||
"title": "Step 47"
|
||||
},
|
||||
{
|
||||
"id": "655a552337ee62882fdeee79",
|
||||
"id": "65d8a90640d40c2927ebbd94",
|
||||
"title": "Step 48"
|
||||
},
|
||||
{
|
||||
"id": "655a557104bb878962e2ae95",
|
||||
"id": "65ca0a1f27596a089b0363b9",
|
||||
"title": "Step 49"
|
||||
},
|
||||
{
|
||||
"id": "655a5607eec63b8c2b1d7087",
|
||||
"id": "65ca0d5adf39c410cd1177cc",
|
||||
"title": "Step 50"
|
||||
},
|
||||
{
|
||||
"id": "655a577302a8a791ed62e8d9",
|
||||
"id": "65ca0dc5dbf42a11c3cf1098",
|
||||
"title": "Step 51"
|
||||
},
|
||||
{
|
||||
"id": "655a5637ad283d8d24dd49de",
|
||||
"id": "65ca0dfaea3f4112afde6e26",
|
||||
"title": "Step 52"
|
||||
},
|
||||
{
|
||||
"id": "655a56a6a1168a8f201ba666",
|
||||
"id": "65ca0e2d05557a13a40b1243",
|
||||
"title": "Step 53"
|
||||
},
|
||||
{
|
||||
"id": "655a56dc4749dc906fac6802",
|
||||
"id": "65ca0e8eb2c9c215269d6a66",
|
||||
"title": "Step 54"
|
||||
},
|
||||
{
|
||||
"id": "655a57bf1d702b936f788b70",
|
||||
"id": "65ca1181e5b9b41c47632127",
|
||||
"title": "Step 55"
|
||||
},
|
||||
{
|
||||
"id": "655a580da8b2419496c88f61",
|
||||
"id": "65ca11a86801bc1d254da83c",
|
||||
"title": "Step 56"
|
||||
},
|
||||
{
|
||||
"id": "655a585b87885d962f715a10",
|
||||
"id": "65ca11d8f3e8a71de41d0e32",
|
||||
"title": "Step 57"
|
||||
},
|
||||
{
|
||||
"id": "655a58897968829714d6e359",
|
||||
"id": "65ca120111bd521ea8b73e75",
|
||||
"title": "Step 58"
|
||||
},
|
||||
{
|
||||
"id": "655a58b2951601981fb893c8",
|
||||
"id": "65ca294e05dc032bf8922dc7",
|
||||
"title": "Step 59"
|
||||
},
|
||||
{
|
||||
"id": "655a5908085cdf99b7630646",
|
||||
"id": "65ca29b3a07d662de018ac13",
|
||||
"title": "Step 60"
|
||||
},
|
||||
{
|
||||
"id": "655a59607b0d2e9b0f5d69e5",
|
||||
"id": "65ca2a18039c942f04ddde83",
|
||||
"title": "Step 61"
|
||||
},
|
||||
{
|
||||
"id": "65ca2a52d579b22feb89177f",
|
||||
"title": "Step 62"
|
||||
}
|
||||
],
|
||||
"helpCategory": "Python"
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
id: 65560ffdb7d05d248e012280
|
||||
title: Step 2
|
||||
challengeType: 20
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the `TreeNode` class, replace `pass` with an `__init__` method so that you can initialize the attributes of the object. Don't add any parameters and use the `pass` keyword to avoid an error.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should define an `__init__` method inside your `TreeNode` class. Remember to use the `pass` keyword.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^\s{4}def\s+__init__\s*\([^(]*\)\s*:/m) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
class TreeNode:
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,83 +0,0 @@
|
||||
---
|
||||
id: 655a51a705c97d7a9294ab2a
|
||||
title: Step 40
|
||||
challengeType: 20
|
||||
dashedName: step-40
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
When the node you want to delete has two children, you need to choose the replacement node from the children.
|
||||
The in-order successor method chooses the smallest element from the right subtree and places that element in place of the deleted node.
|
||||
|
||||
Define the `_min_value` method and give it two parameters: `self` and `node`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should define the `_min_value` method with `self` and `node` as the parameters. Remember to use the `pass` keyword.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /def\s+_min_value\(\s*self\s*,\s*node\s*\)\s*:/) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
class BinarySearchTree:
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
return node
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,87 +0,0 @@
|
||||
---
|
||||
id: 655a54fd97ada88722fa5c8b
|
||||
title: Step 47
|
||||
challengeType: 20
|
||||
dashedName: step-47
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Finally, return the sorted list of keys.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should return the `result` list from your `inorder_traversal` method.
|
||||
|
||||
```js
|
||||
assert.match(code, /return\s+result/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
class BinarySearchTree:
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
return node
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
--fcc-editable-region--
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,103 +0,0 @@
|
||||
---
|
||||
id: 655a56a6a1168a8f201ba666
|
||||
title: Step 53
|
||||
challengeType: 20
|
||||
dashedName: step-53
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Below the `BinarySearchTree` instance, create a list named `nodes` with the following integer values: `50`, `30`, `20`, `40`, `70`, `60`, `80`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a list named `nodes`.
|
||||
|
||||
```js
|
||||
assert.match(code, /nodes/);
|
||||
```
|
||||
|
||||
Your `node` variable should have the value `[50, 30, 20, 40, 70, 60, 80]`.
|
||||
|
||||
```js
|
||||
assert.match(code, /nodes\s*=\s*\[\s*50\s*,\s*30\s*,\s*20\s*,\s*40\s*\s*,\s*70\s*,\s*60\s*,\s*80\s*\]/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
class BinarySearchTree:
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
return node
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
|
||||
--fcc-editable-region--
|
||||
bst = BinarySearchTree()
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,104 +0,0 @@
|
||||
---
|
||||
id: 655a56dc4749dc906fac6802
|
||||
title: Step 54
|
||||
challengeType: 20
|
||||
dashedName: step-54
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a `for` loop to iterate over the `nodes` list. Inside the `for` loop body, call the `insert` method of the `bst` object, passing the node at the current iteration to insert all values orderly into the binary search tree.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `for node in nodes` loop.
|
||||
|
||||
```js
|
||||
assert.match(code, /for\s+node\s+in\s+nodes/);
|
||||
```
|
||||
|
||||
You should have `bst.insert(node)` inside the `for` loop.
|
||||
|
||||
```js
|
||||
assert.match(code, /bst\.insert/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
class BinarySearchTree:
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
return node
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
|
||||
--fcc-editable-region--
|
||||
bst = BinarySearchTree()
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 65560f9380be92226084ef46
|
||||
id: 65c4eb814cc977c95cd7df0e
|
||||
title: Step 1
|
||||
challengeType: 20
|
||||
dashedName: step-1
|
||||
@@ -17,7 +17,7 @@ Begin by defining an empty `TreeNode` class. The `TreeNode` class represents a n
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `class` keyword to declare an empty class named `TreeNode`. Don't forget to add the colon at the end and the `pass` keyword to fill the class body.
|
||||
You should use the `class` keyword to declare an empty class named `TreeNode`.
|
||||
|
||||
```js
|
||||
({
|
||||
@@ -40,4 +40,3 @@ You should use the `class` keyword to declare an empty class named `TreeNode`. D
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: 65c4ef8463f869d0eaf87c67
|
||||
title: Step 2
|
||||
challengeType: 20
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the `TreeNode` class, replace `pass` with an `__init__` method so that you can initialize the attributes of the object. Don't add any parameters for now.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove `pass` keyword from the `TreeNode` class and move it inside the `__init__` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
const pyClassStr = runPython(`str(_Node(_code).find_class("TreeNode"))`);
|
||||
const to_test = pyClassStr.split("\n");
|
||||
assert.notInclude(to_test[1], "pass");
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You should define an `__init__` method inside your `TreeNode` class. Remember to use the `pass` keyword inside.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert(
|
||||
runPython(`_Node(_code).find_class("TreeNode").has_function("__init__")`)
|
||||
);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
class TreeNode:
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 65561022956c1024e7184add
|
||||
id: 65c4f013851cefd1a4fe4c96
|
||||
title: Step 3
|
||||
challengeType: 20
|
||||
dashedName: step-3
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 655a10e4a620fc091ba43b3d
|
||||
id: 65c4f02dbd3557d23f12db62
|
||||
title: Step 4
|
||||
challengeType: 20
|
||||
dashedName: step-4
|
||||
@@ -13,6 +13,21 @@ This means that the `key` attribute of the `TreeNode` instance will be set to th
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` statement from the `__init__` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("TreeNode").find_function("__init__").has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You should assign the value of the `key` parameter to the `key` attribute of the node using `self.key`.
|
||||
|
||||
```js
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 655a1188d6cfbb0a3ec63c57
|
||||
id: 65c4f07da204f4d2f325fbd3
|
||||
title: Step 5
|
||||
challengeType: 20
|
||||
dashedName: step-5
|
||||
@@ -14,13 +14,13 @@ Inside the `__init__` method, initialize the `left` and `right` attributes of th
|
||||
You should assign `None` to the `left` attribute of the node using `self.left`.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^\s{8}self\.left\s*=\s*None/m) })
|
||||
({ test: () => assert.match(code, /self\.left\s*=\s*None/m) })
|
||||
```
|
||||
|
||||
You should assign `None` to the `right` attribute of the node using `self.right`.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^\s{8}self\.right\s*=\s*None/m) })
|
||||
({ test: () => assert.match(code, /self\.right\s*=\s*None/m) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 655a11eb4e54b60acd6bd641
|
||||
id: 65c4f09e074dd8d37830ea00
|
||||
title: Step 6
|
||||
challengeType: 20
|
||||
dashedName: step-6
|
||||
@@ -35,6 +35,7 @@ class TreeNode:
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 655a12c2ab0bcc0c2ba30e16
|
||||
id: 65c4f0b82db314d3fcc0b8e1
|
||||
title: Step 7
|
||||
challengeType: 20
|
||||
dashedName: step-7
|
||||
@@ -11,7 +11,23 @@ Within the `BinarySearchTree` class, replace `pass` with an `__init__` method an
|
||||
|
||||
# --hints--
|
||||
|
||||
You should define an `__init__` method and add a `self` parameter to this method. Remember to use the `pass` keyword.
|
||||
You should remove the `pass` keyword from the `BinarySearchTree` class.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
const pyClassStr = runPython(
|
||||
`str(_Node(_code).find_class("BinarySearchTree"))`
|
||||
);
|
||||
const to_test = pyClassStr.split("\n");
|
||||
assert.notInclude(to_test[1], "pass");
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
|
||||
You should define an `__init__` method and add a `self` parameter to this method. Remember to use the `pass` keyword inside the method body.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^\s{4}def\s+__init__\s*\(\s*self\s*\)\s*:/m) })
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 655a132b56e0160cfeca08d4
|
||||
id: 65c4f0d32ca17ad4b1636b0e
|
||||
title: Step 8
|
||||
challengeType: 20
|
||||
dashedName: step-8
|
||||
@@ -7,12 +7,26 @@ dashedName: step-8
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the `__init__` method, delete `pass` and initialize an instance attribute called `root` to the value `None`.
|
||||
Inside the `__init__` method, delete `pass` and initialize `root` to the value `None`.
|
||||
|
||||
The `root` attribute represents the root node of the binary search tree. Since this is the constructor when a new `BinarySearchTree` object is created, it starts with an empty tree, so the `root` attribute is set to `None`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` statement from the `__init__` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
const pyClassStr = runPython(
|
||||
`str(_Node(_code).find_class("BinarySearchTree"))`
|
||||
);
|
||||
assert.notInclude(pyClassStr, "pass");
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You should initialize the `root` attribute to `None` using `self.root`.
|
||||
|
||||
```js
|
||||
@@ -1,13 +1,15 @@
|
||||
---
|
||||
id: 655a1479ba7e7c0ee6c1acdd
|
||||
title: Step 12
|
||||
id: 65c4f195de7e2ad5932be717
|
||||
title: Step 9
|
||||
challengeType: 20
|
||||
dashedName: step-12
|
||||
dashedName: step-9
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you are going to define an `_insert` method, which is a helper function and does the actual insertion. This method is recursive, meaning it calls itself to traverse the tree until the appropriate location for the new node is found.
|
||||
Next, you need to define a mechanism to insert nodes in the tree. For that, you need to define an `_insert` method, which is a helper function and would be used by the actual `insert` method later on.
|
||||
|
||||
This method is recursive, meaning it calls itself to traverse the tree until the appropriate location for the new node is found.
|
||||
|
||||
Define an `_insert` method with the parameters `self`, `node` and `key`.
|
||||
|
||||
@@ -16,13 +18,13 @@ Define an `_insert` method with the parameters `self`, `node` and `key`.
|
||||
You should define an `_insert` method within the `BinarySearchTree` class. Remember to use `pass`.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^\s{4}def\s+_insert\s*\([^(]*\)\s*:/m) })
|
||||
({ test: () => assert.match(code, /def\s+_insert\s*\([^(]*\)\s*:/m) })
|
||||
```
|
||||
|
||||
Your `_insert` method should take three parameters: `self`, `node` and `key`.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^\s{4}def\s+_insert\s*\(\s*self\s*,\s*node\s*,\s*key\s*\)\s*:/m) })
|
||||
({ test: () => assert.match(code, /def\s+_insert\s*\(\s*self\s*,\s*node\s*,\s*key\s*\)\s*:/m) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -35,15 +37,10 @@ class TreeNode:
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
--fcc-editable-region--
|
||||
class BinarySearchTree:
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,18 +1,27 @@
|
||||
---
|
||||
id: 655a14a6fe4cd50f38d01dd3
|
||||
title: Step 13
|
||||
id: 65c4f22498d22ed775ef8efb
|
||||
title: Step 10
|
||||
challengeType: 20
|
||||
dashedName: step-13
|
||||
dashedName: step-10
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you need to check if the `node` parameter is `None`. If it is, this means that the method has reached a leaf node or an empty spot in the tree where the new node should be inserted.
|
||||
|
||||
Inside the method body, write an `if` statement that checks if `node is None`. Inside the `if` block, return `TreeNode(key)` to create a new `TreeNode` instance with the provided key. This will become the new leaf node, effectively inserting the key into the tree.
|
||||
Inside the `_insert` method body, replace `pass` with an `if` statement that checks if `node is None`. Note that `is` is different from `==`. In Python, `is` checks for object identity. It's used to determine if two variables point to the same object in memory. In contrast to `is`, `==` determines if the values of two objects are the same, regardless of whether they are the same object in memory.
|
||||
|
||||
Inside the new `if` block, return `TreeNode(key)` to create a new `TreeNode` instance with the provided key. This will become the new leaf node, effectively inserting the key into the tree.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should not have `pass` in your `_insert` method.
|
||||
|
||||
```js
|
||||
({ test: () => assert.isFalse(runPython(`_Node(_code).find_class("BinarySearchTree").find_function("_insert").has_pass()`)) })
|
||||
|
||||
```
|
||||
|
||||
You should write an `if` statement to check if `node is None`.
|
||||
|
||||
```js
|
||||
@@ -45,19 +54,19 @@ You should return `TreeNode(key)` from the `if` block.
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _insert(self, node, key):
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a151cc6041f0ff7d24ded
|
||||
title: Step 14
|
||||
id: 65c4f2851645e8d84d14f5d1
|
||||
title: Step 11
|
||||
challengeType: 20
|
||||
dashedName: step-14
|
||||
dashedName: step-11
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -12,14 +12,14 @@ Now you need to recursively traverse the tree and insert the values using the pr
|
||||
- Values smaller than the key are placed in the left subtree
|
||||
- Values greater than the key are placed in the right subtree
|
||||
|
||||
After your existing conditional statement, write another `if` statement to check if `key` is strictly less than `node.key`.
|
||||
After your existing conditional statement, write another `if` statement to check if `key` is less than `node.key`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should write another if statement to check if `key` is strictly less than `node.key`. Remember to use the `pass` keyword.
|
||||
You should write another if statement to check if `key` is less than `node.key`. Remember to use the `pass` keyword.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^(\s{8})if\s+node\s+is\s+None\s*:.*?\1if\s+key\s*<\s*node\.key\s*:/ms) })
|
||||
({ test: () => assert(runPython(` _Node(_code).find_class("BinarySearchTree").find_function("_insert").find_ifs()[1].find_conditions()[0].is_equivalent("key < node.key")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -28,21 +28,22 @@ You should write another if statement to check if `key` is strictly less than `n
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
return TreeNode(key)
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
|
||||
@@ -1,18 +1,32 @@
|
||||
---
|
||||
id: 655a153a6b362d103e125028
|
||||
title: Step 15
|
||||
id: 65c4f2b7178afed8e88f782f
|
||||
title: Step 12
|
||||
challengeType: 20
|
||||
dashedName: step-15
|
||||
dashedName: step-12
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If `key` < `node.key` returns `True`, then the new node should be placed in the left subtree.
|
||||
If `key` < `node.key` evaluates to `True`, then the new node should be placed in the left subtree.
|
||||
|
||||
Delete `pass` and recursively call the `_insert` method on the left child of the current node. Then, assign the result to the `left` attribute of the current node.
|
||||
Delete `pass` and recursively call the `_insert` method with left child as the first argument and `key` as the second argument. Assign the result to the `left` attribute of the current node.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `if` block.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("BinarySearchTree").find_function("_insert").find_if("key < node.key").find_bodies()[0].has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You should call the `self._insert` method passing `node.left` and `key` as the arguments.
|
||||
|
||||
```js
|
||||
@@ -31,23 +45,25 @@ You should assign the result of your `self._insert()` call to the `left` attribu
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
--fcc-editable-region--
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a1564f3aa8210938cdf68
|
||||
title: Step 16
|
||||
id: 65c4f2d9fd872fd99ac659dd
|
||||
title: Step 13
|
||||
challengeType: 20
|
||||
dashedName: step-16
|
||||
dashedName: step-13
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -14,13 +14,7 @@ Add an `elif` conditional statement that checks if `key` > `node.key`.
|
||||
You should add an `elif` conditional statement to check if `key > node.key`. Remember to use the `pass` keyword.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () =>
|
||||
assert.match(
|
||||
code,
|
||||
/^(\s+)if\s+node\s+is\s+None\s*:.*?\1elif\s+key\s*>\s*node\.key\s*:/ms
|
||||
)
|
||||
});
|
||||
({ test: () => assert(runPython(`_Node(_code).find_class("BinarySearchTree").find_function("_insert").find_ifs()[1].find_conditions()[1].is_equivalent("key > node.key")`))})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -29,23 +23,27 @@ You should add an `elif` conditional statement to check if `key > node.key`. Rem
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
--fcc-editable-region--
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
|
||||
@@ -1,16 +1,30 @@
|
||||
---
|
||||
id: 655a158c7e80c810f6eff1e1
|
||||
title: Step 17
|
||||
id: 65c4f300da28d8da361bfa93
|
||||
title: Step 14
|
||||
challengeType: 20
|
||||
dashedName: step-17
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside your `elif` clause, replace `pass` with a call to the `_insert` method on the right child of the current node. Assign the result to the `right` attribute of the current node.
|
||||
Inside your `elif` clause, replace `pass` with a call to the `_insert` method with right child of the current node as the first argument and `key` as the second argument. Assign the result to the `right` attribute of the current node.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `elif` block.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
const pyClassStr = runPython(
|
||||
`str(_Node(_code).find_class("BinarySearchTree"))`
|
||||
);
|
||||
assert.notInclude(pyClassStr, "pass");
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You should call the `self._insert()` method passing `node.right` and `key` as the arguments.
|
||||
|
||||
```js
|
||||
@@ -23,31 +37,35 @@ You should assign the result of your `self._insert()` call to the right attribut
|
||||
({ test: () => assert.match(code, /node\.right\s*=\s*self\._insert\(\s*node\.right\s*,\s*key\s*\)/) });
|
||||
```
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
--fcc-editable-region--
|
||||
elif key > node.key:
|
||||
pass
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a15b683445611528cccf1
|
||||
title: Step 18
|
||||
id: 65c4f3258d2e4cdacc919dfd
|
||||
title: Step 15
|
||||
challengeType: 20
|
||||
dashedName: step-18
|
||||
dashedName: step-15
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -22,6 +22,7 @@ You should return the current node outside the conditional blocks.
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
def __init__(self, key):
|
||||
@@ -33,16 +34,16 @@ class BinarySearchTree:
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
--fcc-editable-region--
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._insert(node.right, key)
|
||||
node.right = self._insert(node.right, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
id: 655a13744e82580d7ee3073d
|
||||
title: Step 9
|
||||
id: 65c4f33bc3c3d8db7f732787
|
||||
title: Step 16
|
||||
challengeType: 20
|
||||
dashedName: step-9
|
||||
dashedName: step-16
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Next, you need to define a mechanism to insert nodes in the tree. For that, define an empty `insert` method within the `BinarySearchTree` class and give it a `self` parameter.
|
||||
Now, to perform the actual insertion, define an empty `insert` method within the `BinarySearchTree` class and give it a `self` parameter.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -27,11 +27,21 @@ class TreeNode:
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
--fcc-editable-region--
|
||||
|
||||
class BinarySearchTree:
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a13aa8af2510de51f2e1c
|
||||
title: Step 10
|
||||
id: 65c4f37ba6cbcfdc77e24165
|
||||
title: Step 17
|
||||
challengeType: 20
|
||||
dashedName: step-10
|
||||
dashedName: step-17
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -29,6 +29,7 @@ The `insert` method should contain the `key` parameter.
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
|
||||
```py
|
||||
class TreeNode:
|
||||
def __init__(self, key):
|
||||
@@ -37,11 +38,23 @@ class TreeNode:
|
||||
self.right = None
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
--fcc-editable-region--
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
--fcc-editable-region--
|
||||
def insert(self):
|
||||
pass
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
@@ -1,13 +1,14 @@
|
||||
---
|
||||
id: 655a142ae611b30e5df0ac16
|
||||
title: Step 11
|
||||
id: 65c4f3aee69d11dcfdbcfc00
|
||||
title: Step 18
|
||||
challengeType: 20
|
||||
dashedName: step-11
|
||||
dashedName: step-18
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now, inside the `insert` method, you need to call another method `_insert()` that performs the actual insertion. You are going to define the `_insert` method soon.
|
||||
Now, inside the `insert` method, you need to call the helper method `_insert()` that we defined earlier.
|
||||
Here, `_insert` has encapsulated the implementation of the insertion logic. This is useful for recursion and for keeping the implementation details hidden from the user.
|
||||
|
||||
Delete `pass` and assign `self._insert(self.root, key)` to `self.root`.
|
||||
|
||||
@@ -18,6 +19,21 @@ Note that:
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `insert` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("BinarySearchTree").find_function("insert").has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You should recursively call the `_insert()` method using `self._insert()`
|
||||
|
||||
```js
|
||||
@@ -62,18 +78,35 @@ You should assign the return value of your `_insert()` call to `self.root`.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
--fcc-editable-region--
|
||||
def insert(self,key):
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def insert(self, key):
|
||||
pass
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,13 +1,15 @@
|
||||
---
|
||||
id: 655a173e5b8adc13b761ed74
|
||||
title: Step 22
|
||||
id: 65c63a4c4da62e9ae18e321a
|
||||
title: Step 19
|
||||
challengeType: 20
|
||||
dashedName: step-22
|
||||
dashedName: step-19
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now, define the `_search` method with three parameters, namely `self`,`node` and `key`.
|
||||
It's time to work on the search functionality. Just like you created a helper method `_insert` for the `insert` method, you need to create a helper method `_search` for the `search` method.
|
||||
|
||||
Define the `_search` method with three parameters, namely `self`,`node` and `key`.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -28,32 +30,34 @@ Your `_search` method should take three parameters: `self`, `node`, and `key`.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
--fcc-editable-region--
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
id: 655a194276dfa11460f7b5e3
|
||||
title: Step 23
|
||||
id: 65c63da2ed6769a10e141341
|
||||
title: Step 20
|
||||
challengeType: 20
|
||||
dashedName: step-23
|
||||
dashedName: step-20
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you are going to define a base case for the recursive search. Write an `if` statement that checks two conditions:
|
||||
Now you are going to define a base case for the recursive search. Remove the current `pass` and write an `if` statement that checks two conditions:
|
||||
|
||||
- If `node` is `None`: This indicates that the search has reached the end of a branch without finding the key.
|
||||
- If `node.key == key`: This means that the key has been found in the current node.
|
||||
@@ -16,6 +16,21 @@ Combine the two conditions with the `or` operator and return the current node in
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `_search` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("BinarySearchTree").find_function("_search").has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You should write an `if` statement that checks if `node` is `None` or if `node.key` is equal to `key`.
|
||||
|
||||
```js
|
||||
@@ -33,33 +48,37 @@ You should return `node` from the `if` block.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _search(self, node, key):
|
||||
pass
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a1a6d8c44db154b00c909
|
||||
title: Step 24
|
||||
id: 65c63df529bd15a24c187c62
|
||||
title: Step 21
|
||||
challengeType: 20
|
||||
dashedName: step-24
|
||||
dashedName: step-21
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -16,14 +16,13 @@ Inside the `if` block, return the result of calling the `_search` method with th
|
||||
You should write another `if` statement to check if `key` < `node.key`.
|
||||
|
||||
```js
|
||||
const after_split = code.split('def search(self, key):')[1];
|
||||
assert.match(after_split, /if\s+key\s+<\s+node\.key/);
|
||||
({ test: () => assert(runPython(`_Node(_code).find_class("BinarySearchTree").find_function("_search").find_ifs()[1].find_conditions()[0].is_equivalent("key < node.key")`)) })
|
||||
```
|
||||
|
||||
You should return `self._search(node.left, key)` from your new `if` block.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /return\s+self\._search\(\s*node\.left\s*,\s*key\s*\)/) });
|
||||
({ test: () => assert(runPython(`_Node(_code).find_class("BinarySearchTree").find_function("_search").find_ifs()[1].find_bodies()[0].is_equivalent("return self._search(node.left, key)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -31,33 +30,38 @@ You should return `self._search(node.left, key)` from your new `if` block.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
return node
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a44442b60ee5a28df8ee5
|
||||
title: Step 25
|
||||
id: 65c63e6962159fa372ecdbec
|
||||
title: Step 22
|
||||
challengeType: 20
|
||||
dashedName: step-25
|
||||
dashedName: step-22
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -41,35 +41,40 @@ You should return the result of the `_search` method call.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.left, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
id: 655a227e57aabb25d1f9c987
|
||||
title: Step 19
|
||||
id: 65c63eb01b9563a4b8a046b6
|
||||
title: Step 23
|
||||
challengeType: 20
|
||||
dashedName: step-19
|
||||
dashedName: step-23
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now, it's time to work on the search functionality.
|
||||
|
||||
Define a method named `search` inside the `BinarySearchTree` class. Give the `search` method two parameters: `self` and `key`.
|
||||
|
||||
Next, define the method named `search` inside the `BinarySearchTree` class. Give the `search` method two parameters: `self` and `key`.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -31,29 +28,42 @@ The `search` method should take two parameters: `self` and `key`.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,21 +1,36 @@
|
||||
---
|
||||
id: 655a167ea3e96512bf1343ce
|
||||
title: Step 20
|
||||
id: 65c63fd9b387f0a6c5bf6a72
|
||||
title: Step 24
|
||||
challengeType: 20
|
||||
dashedName: step-20
|
||||
dashedName: step-24
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the `search` method, delete `pass` and call the private helper method `_search` with the following arguments. You will define `_search` in the next steps.
|
||||
Inside the `search` method, delete `pass` and call the helper method `_search` with the following arguments.
|
||||
|
||||
- `self.root`: This is the root of the binary search tree. The search starts from the root.
|
||||
- `key`: This is the value that the user wants to find in the binary search tree.
|
||||
|
||||
Internally, `search` delegates the actual search logic to the private `_search` method that performs the actual recursive search within the binary search tree.
|
||||
Internally, `search` delegates the actual search logic to the `_search` helper method that performs the actual recursive search within the binary search tree.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `search` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("BinarySearchTree").find_function("search").has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You should call the `_search` method within the `search` method.
|
||||
|
||||
```js
|
||||
@@ -33,29 +48,42 @@ You should call the `_search` method passing `self.root` and `key` as the argume
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a16db1ccc5e132b5bc44d
|
||||
title: Step 21
|
||||
id: 65c64057a080baa7d60523ed
|
||||
title: Step 25
|
||||
challengeType: 20
|
||||
dashedName: step-21
|
||||
dashedName: step-25
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -22,29 +22,44 @@ You should prepend the `return` statement to your `_search()` call.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
id: 65c6409418806da8d0636ffc
|
||||
title: Step 26
|
||||
challengeType: 20
|
||||
dashedName: step-26
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The `insert` and `search` functionalities are complete, it's time to test them.
|
||||
|
||||
Note that, at this point, the nodes are not sorted and just inserted. You'll work on sorting using inorder traversal later on.
|
||||
|
||||
You can create an instance of a class in Python like this:
|
||||
|
||||
```python
|
||||
object_name = ClassName()
|
||||
```
|
||||
|
||||
Outside the class definitions, create an instance of the `BinarySearchTree` class and assign it to the variable `bst`.
|
||||
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an instance of the `BinarySearchTree` class.
|
||||
|
||||
```js
|
||||
assert.match(code, /BinarySearchTree\(\s*\)/);
|
||||
```
|
||||
|
||||
You should assign the new instance of `BinarySearchTree` to the variable `bst`.
|
||||
|
||||
```js
|
||||
assert.match(code, /bst\s*=\s*BinarySearchTree\(\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 655a4614304cd36031cb4e75
|
||||
id: 65c644829cfb63acf3479d09
|
||||
title: Step 28
|
||||
challengeType: 20
|
||||
dashedName: step-28
|
||||
@@ -7,16 +7,20 @@ dashedName: step-28
|
||||
|
||||
# --description--
|
||||
|
||||
The deletion operation might result in a new root (for example, if the node to be deleted is the current root).
|
||||
|
||||
To handle this case, assign the result of the `_delete` call to `self.root`.
|
||||
Insert the nodes in the list `nodes` into the `bst` instance by iterating over the list and calling the `insert` method on each node in the list. Use `node` as the iteration variable.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should assign the result of the `_delete()` call to `self.root`.
|
||||
You should have a `for node in nodes` loop.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /self\.root\s*=\s*self\._delete\(\s*self\.root\s*,\s*key\s*\)/) });
|
||||
assert.match(code, /for\s+node\s+in\s+nodes/);
|
||||
```
|
||||
|
||||
You should have `bst.insert(node)` inside the `for` loop.
|
||||
|
||||
```js
|
||||
assert.match(code, /bst\.insert/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -24,39 +28,48 @@ You should assign the result of the `_delete()` call to `self.root`.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def delete(self, key):
|
||||
self._delete(self.root, key)
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
id: 65c645b838e7deb080fc25e0
|
||||
title: Step 29
|
||||
challengeType: 20
|
||||
dashedName: step-29
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now, the nodes have been inserted. To see if they have been correctly inserted, you can search for a node in the tree.
|
||||
|
||||
Outside the for loop, search for node `80` in the `bst` instance and add it to a `print` call. Also the first argument of the `print` function should be the `'Search for 80:'`
|
||||
|
||||
# --hints--
|
||||
|
||||
You should print the result of calling `bst.search(80)` and your `print` statement should have the first argument as `'Search for 80:'`.
|
||||
|
||||
```js
|
||||
assert.match(code, /^print\(('|")Search for 80:('|"),\s*bst\.search\(80\)/gm);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
id: 65c646d4148ae3b2d1cbcac4
|
||||
title: Step 30
|
||||
challengeType: 20
|
||||
dashedName: step-30
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Note that, your search returns something like `80: <__main__.TreeNode object at 0x108b3e0>`. This is the default string representation when printing an instance of a class.
|
||||
|
||||
To change that to print a useful value, define another method named `__str__` in the `TreeNode` class. It takes a single argument `self`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should define a method `__str__` that takes a single argument `self`. Remember to use `pass`.
|
||||
|
||||
```js
|
||||
assert.match(code, /def\s+__str__\(\s*self\s*\)/);
|
||||
```
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
print('Search for 80:', bst.search(80))
|
||||
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
id: 65c9ddd336596e30a4266a50
|
||||
title: Step 31
|
||||
challengeType: 20
|
||||
dashedName: step-31
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In the body of the `__str__` method, delete `pass` and return the result of calling the `str()` function with `self.key` as the argument. This is the attribute of the current node object that stores the value associated with the node.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `__str__` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("TreeNode").find_function("__str__").has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You should return the string value of `self.key` from your `__str__` method.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^\s{8}return\s+str\(\s*self\.key\s*\)/m) })
|
||||
```
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
--fcc-editable-region--
|
||||
def __str__(self):
|
||||
pass
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
print('Search for 80:', bst.search(80))
|
||||
|
||||
```
|
||||
@@ -1,24 +1,22 @@
|
||||
---
|
||||
id: 655a452d40556e5c25e4aac8
|
||||
title: Step 26
|
||||
id: 65c9de201959f73591b606e6
|
||||
title: Step 32
|
||||
challengeType: 20
|
||||
dashedName: step-26
|
||||
dashedName: step-32
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The next step is to work on the deletion of nodes.
|
||||
As you can see, now you get a readable output in the console.
|
||||
|
||||
Within the `BinarySearchTree` class, define a `delete` method. It takes two parameters: `self` and `key`.
|
||||
|
||||
`key` is the value that the user wants to delete from the binary search tree.
|
||||
Now, comment out the `print` call.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should define a `delete` method with two parameters: `self` and `key`. Remember to use `pass`.
|
||||
You should comment out the line `print('Search for 80:', bst.search(80))`
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /def\s+delete\(\s*self\s*,\s*key\s*\)/) });
|
||||
assert(code.match(/#\s*print\s*\(\s*'Search\s*for\s*80:\s*',\s*bst\.search\s*\(\s*80\s*\)\s*\)/));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -26,38 +24,58 @@ You should define a `delete` method with two parameters: `self` and `key`. Remem
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
--fcc-editable-region--
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
print('Search for 80:', bst.search(80))
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
@@ -1,12 +1,15 @@
|
||||
---
|
||||
id: 655a46aa8e10c26218c5034c
|
||||
title: Step 29
|
||||
id: 65ca03bd8eb5faf24b250c56
|
||||
title: Step 33
|
||||
challengeType: 20
|
||||
dashedName: step-29
|
||||
dashedName: step-33
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The next step is to work on the deletion of nodes.
|
||||
For that, you would follow the same approach by first defining a helper method and then the actual method.
|
||||
|
||||
Inside the `BinarySearchTree` class, define a new helper method called `_delete` that takes three parameters: `self`, `node`, and `key`.
|
||||
|
||||
# --hints--
|
||||
@@ -14,7 +17,7 @@ Inside the `BinarySearchTree` class, define a new helper method called `_delete`
|
||||
You should define the `_delete` method inside the `BinarySearchTree` class with the parameters `self`, `node` and `key`. Remember to use the `pass` keyword.
|
||||
|
||||
```js
|
||||
assert.match(code, /def\s+_delete\(\s*self\s*,\s*node\s*,\s*key\s*\)/);
|
||||
({ test: () => assert.match(code, /def\s+_delete\(\s*self\s*,\s*node\s*,\s*key\s*\)/) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -22,41 +25,58 @@ assert.match(code, /def\s+_delete\(\s*self\s*,\s*node\s*,\s*key\s*\)/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
--fcc-editable-region--
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
```
|
||||
@@ -1,18 +1,33 @@
|
||||
---
|
||||
id: 655a46fce0ce5a638c180e36
|
||||
title: Step 30
|
||||
id: 65ca05f7cba1e6fe70527534
|
||||
title: Step 34
|
||||
challengeType: 20
|
||||
dashedName: step-30
|
||||
dashedName: step-34
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside your `_delete` method, replace `pass` with an `if` statement that checks if the current `node` is `None`. When the current node is `None`, the key to be deleted was not found.
|
||||
Inside your `_delete` method, replace `pass` with an `if` statement that checks if the current `node` is `None`.
|
||||
|
||||
Therefore, return `node` from your `if` block.
|
||||
When the current node is `None`, the key to be deleted was not found. Therefore, return `node` from your `if` block.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `_delete` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("BinarySearchTree").find_function("_delete").has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You should write an `if` statement that checks if the current `node` is `None`.
|
||||
|
||||
```js
|
||||
@@ -32,43 +47,59 @@ assert.match(after_split, /return\s+node/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _delete(self, node, key):
|
||||
pass
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a4761e1a40065fc4d3712
|
||||
title: Step 31
|
||||
id: 65ca06475e9b8aff8ea5a5f1
|
||||
title: Step 35
|
||||
challengeType: 20
|
||||
dashedName: step-31
|
||||
dashedName: step-35
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -14,8 +14,7 @@ After your existing `if`, write another one that checks if the target key is les
|
||||
You should have an `if` condition that checks if `key` is less than `node.key`. Remember to use `pass`.
|
||||
|
||||
```js
|
||||
const after_split = code.split('def _delete(self, node, key):')[1];
|
||||
assert.match(after_split, /if\s+key\s+<\s+node\.key/);
|
||||
({ test: () => assert(runPython(`_Node(_code).find_class("BinarySearchTree").find_function("_delete").find_ifs()[1].find_conditions()[0].is_equivalent("key < node.key")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -23,44 +22,61 @@ assert.match(after_split, /if\s+key\s+<\s+node\.key/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
return node
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a47a9404d856743c7f529
|
||||
title: Step 32
|
||||
id: 65ca06864129380054b55dc0
|
||||
title: Step 36
|
||||
challengeType: 20
|
||||
dashedName: step-32
|
||||
dashedName: step-36
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -11,6 +11,20 @@ Within the `if` block, replace `pass` with a call to the `_delete` method, passi
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `if` statement.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("BinarySearchTree").find_function("_delete").find_if("key < node.key").find_bodies()[0].has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You should call the `_delete` method with `node.left` and the `key` as the arguments.
|
||||
|
||||
```js
|
||||
@@ -28,40 +42,45 @@ assert.match(code, /node\.left\s*=\s*self\._delete\(\s*node\.left\s*,\s*key\s*\)
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _delete(self, node, key):
|
||||
@@ -69,5 +88,17 @@ class BinarySearchTree:
|
||||
return node
|
||||
if key < node.key:
|
||||
pass
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a482dfc92896901b9c97e
|
||||
title: Step 33
|
||||
id: 65ca06c9f918730107c9908d
|
||||
title: Step 37
|
||||
challengeType: 20
|
||||
dashedName: step-33
|
||||
dashedName: step-37
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -37,40 +37,45 @@ assert.match(code, /node\.right\s*=\s*self\._delete\(\s*node\.right\s*,\s*key\s*
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _delete(self, node, key):
|
||||
@@ -78,5 +83,17 @@ class BinarySearchTree:
|
||||
return node
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a489d83b1996bd537b153
|
||||
title: Step 34
|
||||
id: 65ca071d5921760254949f76
|
||||
title: Step 38
|
||||
challengeType: 20
|
||||
dashedName: step-34
|
||||
dashedName: step-38
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -16,7 +16,7 @@ For that, add an `else` clause to the conditional.
|
||||
You should add an `else` clause. Remember to use the `pass` keyword.
|
||||
|
||||
```js
|
||||
assert.match(code, /else\s*:/);
|
||||
({ test: () => assert(runPython(`_Node(_code).find_class("BinarySearchTree").find_function("_delete").find_ifs()[1].find_conditions()[2].tree is None`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -24,40 +24,45 @@ assert.match(code, /else\s*:/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _delete(self, node, key):
|
||||
@@ -66,6 +71,18 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a48da2c25656d2f7bab4d
|
||||
title: Step 35
|
||||
id: 65ca075e3184180309f4c1d9
|
||||
title: Step 39
|
||||
challengeType: 20
|
||||
dashedName: step-35
|
||||
dashedName: step-39
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -13,6 +13,19 @@ When `node.left` is `None`, there is no left child. Therefore, return the right
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `else` block.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
const pyClassStr = runPython(
|
||||
`str(_Node(_code).find_class("BinarySearchTree").find_function("_delete"))`
|
||||
);
|
||||
assert.notInclude(pyClassStr, "pass");
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You should write an `if` statement that checks if `node.left` is `None`.
|
||||
|
||||
```js
|
||||
@@ -30,50 +43,66 @@ assert.match(code, /return\s+node\.right/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
--fcc-editable-region--
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
pass
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a493ab909a96f7c316cd5
|
||||
title: Step 36
|
||||
id: 65ca0794ec3ed103bca67ed7
|
||||
title: Step 40
|
||||
challengeType: 20
|
||||
dashedName: step-36
|
||||
dashedName: step-40
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -16,13 +16,13 @@ If the previous condition is met, it means there is no right child. So, return t
|
||||
You should create an `elif` statement that checks if the right child of the current node is `None`.
|
||||
|
||||
```js
|
||||
assert.match(code, /elif\s+node\.right\s+is\s+None/);
|
||||
({test: () => assert(runPython(`_Node(_code).find_class("BinarySearchTree").find_function("_delete").find_ifs()[1].find_conditions()[3].is_equivalent("node.right is None")`))})
|
||||
```
|
||||
|
||||
You should return the left child of the current node.
|
||||
|
||||
```js
|
||||
assert.match(code, /return\s+node\.left/);
|
||||
({test: () => assert(runPython(`_Node(_code).find_class("BinarySearchTree").find_function("_delete").find_ifs()[1].find_bodies()[3].is_equivalent("return node.left")`))})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -30,51 +30,67 @@ assert.match(code, /return\s+node\.left/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
--fcc-editable-region--
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a4ffc762d117470b94e3b
|
||||
title: Step 37
|
||||
id: 65ca07dd6fa8840491b7a5cd
|
||||
title: Step 41
|
||||
challengeType: 20
|
||||
dashedName: step-37
|
||||
dashedName: step-41
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -12,16 +12,14 @@ If neither one of the previous conditions is met, it means the node has both lef
|
||||
To choose the successor, you need to find the minimum value in the right subtree.
|
||||
The smallest value will be the in-order successor of the current node.
|
||||
|
||||
Later on, you are going to define a helper method called `_min_value` that finds the smallest value in a given subtree.
|
||||
|
||||
For now, add a `_min_value` call after your `elif` block, passing `node.right` as the argument. Assign it to the current node key.
|
||||
To find the smallest value, create a helper function `_min_value` that takes two parameters: `self` and `node`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should assign `self._min_value(node.right)` to `node.key` after your `elif` block.
|
||||
You should define the `_min_value` method with `self` and `node` as the parameters. Remember to use the `pass` keyword.
|
||||
|
||||
```js
|
||||
assert.match(code, /node\.key\s*=\s*self\._min_value\(\s*node\.right\s*\)/);
|
||||
({ test: () => assert.match(code, /def\s+_min_value\(\s*self\s*,\s*node\s*\)\s*:/) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -29,40 +27,45 @@ assert.match(code, /node\.key\s*=\s*self\._min_value\(\s*node\.right\s*\)/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -70,12 +73,24 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
--fcc-editable-region--
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
return node.left
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a523d4bbc8b7d3848d7dd
|
||||
title: Step 42
|
||||
id: 65ca085a19adaa057302a3d6
|
||||
title: Step 43
|
||||
challengeType: 20
|
||||
dashedName: step-42
|
||||
dashedName: step-43
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -11,6 +11,20 @@ Inside the `while` loop body, replace `pass` with `node` and assign it the left
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `while` loop.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
const pyClassStr = runPython(
|
||||
`str(_Node(_code).find_class("BinarySearchTree").find_function("_min_value"))`
|
||||
);
|
||||
assert.notInclude(pyClassStr, "pass");
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You should assign `node.left` to `node` inside your `while` loop.
|
||||
|
||||
```js
|
||||
@@ -22,40 +36,45 @@ You should assign `node.left` to `node` inside your `while` loop.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -63,21 +82,27 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
return node
|
||||
|
||||
return node.left
|
||||
|
||||
--fcc-editable-region--
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 655a5489c62889851c60ff4b
|
||||
id: 65ca089e848eca0672b9cd77
|
||||
title: Step 45
|
||||
challengeType: 20
|
||||
dashedName: step-45
|
||||
@@ -7,14 +7,16 @@ dashedName: step-45
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the method, replace `pass` with an empty list named `result` that will store the keys of the nodes in sorted order.
|
||||
Now, back to the `_delete` method, you have to choose the successor, using the `_min_value` helper function.
|
||||
|
||||
Add a `_min_value` call after your `elif` block, passing `node.right` as the argument. Assign it to the current node key.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should initialize an empty list named `result` inside the method.
|
||||
You should assign `self._min_value(node.right)` to `node.key` after your `elif` block.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /result\s*=\s*\[\s*\]/) })
|
||||
assert.match(code, /node\.key\s*=\s*self\._min_value\(\s*node\.right\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -22,66 +24,75 @@ You should initialize an empty list named `result` inside the method.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
return node
|
||||
|
||||
return node.left
|
||||
|
||||
--fcc-editable-region--
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
--fcc-editable-region--
|
||||
def inorder_traversal(self):
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
|
||||
```
|
||||
@@ -1,20 +1,37 @@
|
||||
---
|
||||
id: 655a5908085cdf99b7630646
|
||||
title: Step 60
|
||||
id: 65ca0a1f27596a089b0363b9
|
||||
title: Step 49
|
||||
challengeType: 20
|
||||
dashedName: step-60
|
||||
dashedName: step-49
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Corfirm that `40` has been deleted by printing the tree. After deleting `40`, call `print()` passing the string `Inorder traversal after deleting 40:` as the first argument and an `inorder_traversal()` call as the second argument.
|
||||
Inside the `delete` method, delete `pass` and call the helper method `_delete` with the root of the Binary Search Tree and the key to delete as the arguments.
|
||||
|
||||
Also, assign the result of the `_delete` method to `self.root` in the `delete` method.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call `print` passing the string `Inorder traversal after deleting 40:` as the first argument and an `inorder_traversal()` call as the second argument.
|
||||
You should remove the `pass` keyword from the `delete` method.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^print\s*\(\s*("|')Inorder traversal after deleting 40:\1\s*,\s*bst\.inorder_traversal\s*\(\s*\)\s*\)/m) })
|
||||
({ test: () => {
|
||||
assert.isFalse(runPython(`_Node(_code).find_class("BinarySearchTree").find_function("delete").has_pass()`))
|
||||
}})
|
||||
```
|
||||
|
||||
Your `delete` method should call the `_delete` method with two arguments: `self.root` and `key`.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /self\._delete\(\s*self\.root\s*,\s*key\s*\)/) });
|
||||
```
|
||||
|
||||
You should assign the result of the `_delete` method to `self.root` in the `delete` method.
|
||||
|
||||
```js
|
||||
const after_split = code.split('def delete(self, key):')[1];
|
||||
assert.match(after_split, /self\.root\s*=\s*self\._delete\(self\.root,\s*key\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -22,7 +39,9 @@ You should call `print` passing the string `Inorder traversal after deleting 40:
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
@@ -31,35 +50,34 @@ class TreeNode:
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -67,44 +85,37 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
|
||||
--fcc-editable-region--
|
||||
def delete(self, key):
|
||||
pass
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
print("Inorder traversal:", bst.inorder_traversal())
|
||||
print("Search for 40:", bst.search(40))
|
||||
bst.delete(40)
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,20 +1,22 @@
|
||||
---
|
||||
id: 655a580da8b2419496c88f61
|
||||
title: Step 56
|
||||
id: 65ca0d5adf39c410cd1177cc
|
||||
title: Step 50
|
||||
challengeType: 20
|
||||
dashedName: step-56
|
||||
dashedName: step-50
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Below your `print()` call, add another `print()` call to test the search functionality. This time, pass the string `Search for 40:` as the first argument. For the second argument, call the `search` method of `bst` and pass `40` as the argument.
|
||||
Now, you'll work on traversing the tree based on the in-order traversal method. In-order traversal is a depth-first binary tree traversal algorithm that visits the left subtree, the current node, and then the right subtree.
|
||||
|
||||
Define the `_inorder_traversal` method within the `BinarySearchTree` class and give it three parameters: `self`, `node` and `result`. Where `node` is the current node being considered during the traversal and `result` is the list to which the keys are appended in sorted order.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call `print()` and pass the string `Search for 40:` and the `bst.search(40)` call as the arguments.
|
||||
You should define a method `_inorder_traversal` that takes three parameters: `self`, `node`, and `result`. Remember to use `pass`.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^print\s*\(\s*("|')Search for 40:\1\s*,\s*bst\.search\s*\(\s*40\s*\)\s*\)/m) })
|
||||
assert.match(code, /def\s+_inorder_traversal\(\s*self\s*,\s*node\s*,\s*result\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -22,40 +24,45 @@ You should call `print()` and pass the string `Search for 40:` and the `bst.sear
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -63,42 +70,38 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
print("Inorder traversal:", bst.inorder_traversal())
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a557104bb878962e2ae95
|
||||
title: Step 49
|
||||
id: 65ca0dc5dbf42a11c3cf1098
|
||||
title: Step 51
|
||||
challengeType: 20
|
||||
dashedName: step-49
|
||||
dashedName: step-51
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -11,6 +11,21 @@ Replace `pass` with an `if` statement that checks if the current node (`node`) i
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the existing `pass` keyword from the `_inorder_traversal` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("BinarySearchTree").find_function("_inorder_traversal").has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
Your check condition should be `if node`.
|
||||
|
||||
```js
|
||||
@@ -28,40 +43,45 @@ assert.match(code, /self\._inorder_traversal\(\s*node\.left\s*,\s*result\s*\)/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -69,28 +89,39 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
--fcc-editable-region--
|
||||
def _inorder_traversal(self, node, result):
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a5607eec63b8c2b1d7087
|
||||
title: Step 50
|
||||
id: 65ca0dfaea3f4112afde6e26
|
||||
title: Step 52
|
||||
challengeType: 20
|
||||
dashedName: step-50
|
||||
dashedName: step-52
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -22,40 +22,45 @@ assert.match(code, /result\.append\(\s*node\.key\s*\)/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -63,29 +68,41 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
--fcc-editable-region--
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
self._inorder_traversal(node.left, result)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a577302a8a791ed62e8d9
|
||||
title: Step 51
|
||||
id: 65ca0e2d05557a13a40b1243
|
||||
title: Step 53
|
||||
challengeType: 20
|
||||
dashedName: step-51
|
||||
dashedName: step-53
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -16,7 +16,7 @@ This recursive call explores the entire right subtree in an in-order manner.
|
||||
You should call `_inorder_traversal` passing `node.right` and `result` as the arguments.
|
||||
|
||||
```js
|
||||
assert.match(code, /self\._inorder_traversal\(\s*node\.right\s*,\s*result\s*\)/);
|
||||
({test: () => assert(runPython(`_Node(_code).find_class("BinarySearchTree").find_function("_inorder_traversal").find_ifs()[0].find_bodies()[0].find_body()[2].is_equivalent("self._inorder_traversal(node.right, result)")`))})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -24,40 +24,45 @@ assert.match(code, /self\._inorder_traversal\(\s*node\.right\s*,\s*result\s*\)/)
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -65,30 +70,42 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
--fcc-editable-region--
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,15 +1,13 @@
|
||||
---
|
||||
id: 655a536e99be288210f01451
|
||||
title: Step 44
|
||||
id: 65ca0e8eb2c9c215269d6a66
|
||||
title: Step 54
|
||||
challengeType: 20
|
||||
dashedName: step-44
|
||||
dashedName: step-54
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The `inorder_traversal` method is responsible for performing an in-order traversal of the binary search tree. It returns the keys of the nodes in sorted order.
|
||||
|
||||
In-order traversal is a depth-first binary tree traversal algorithm that visits the left subtree, the current node, and then the right subtree.
|
||||
The `inorder_traversal` method is responsible for performing an in-order traversal of the binary search tree. It returns the keys of the nodes in sorted order. It will use the helper method `_inorder_traversal` to achieve this.
|
||||
|
||||
Create an `inorder_traversal` method that takes `self` as the only parameter.
|
||||
|
||||
@@ -26,40 +24,45 @@ You should define an `inorder_traversal` method that takes `self` as the paramet
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -67,23 +70,43 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
--fcc-editable-region--
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -0,0 +1,125 @@
|
||||
---
|
||||
id: 65ca1181e5b9b41c47632127
|
||||
title: Step 55
|
||||
challengeType: 20
|
||||
dashedName: step-55
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the `inorder_traversal` method, replace `pass` with an empty list named `result` that will store the keys of the nodes in sorted order.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `pass` keyword from the `inorder_traversal` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("BinarySearchTree").find_function("inorder_traversal").has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You should initialize an empty list named `result` inside the method.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /result\s*=\s*\[\s*\]/) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
--fcc-editable-region--
|
||||
def inorder_traversal(self):
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a54cd88e33b8646c67e16
|
||||
title: Step 46
|
||||
id: 65ca11a86801bc1d254da83c
|
||||
title: Step 56
|
||||
challengeType: 20
|
||||
dashedName: step-46
|
||||
dashedName: step-56
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -24,40 +24,45 @@ You should call `_inorder_traversal` and pass `self.root` and `result` as the ar
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -65,24 +70,45 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
--fcc-editable-region--
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,28 +1,20 @@
|
||||
---
|
||||
id: 655a5637ad283d8d24dd49de
|
||||
title: Step 52
|
||||
id: 65ca11d8f3e8a71de41d0e32
|
||||
title: Step 57
|
||||
challengeType: 20
|
||||
dashedName: step-52
|
||||
dashedName: step-57
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now it's time to put everything into use.
|
||||
|
||||
Create an instance of the `BinarySearchTree` class and assign it to the variable `bst`.
|
||||
Finally, return the sorted list of keys.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an instance of the `BinarySearchTree` class.
|
||||
You should return the `result` list from your `inorder_traversal` method.
|
||||
|
||||
```js
|
||||
assert.match(code, /BinarySearchTree\(\s*\)/);
|
||||
```
|
||||
|
||||
You should assign the new instance of `BinarySearchTree` to the variable `bst`.
|
||||
|
||||
```js
|
||||
assert.match(code, /bst\s*=\s*BinarySearchTree\(\s*\)/);
|
||||
assert.match(code, /return\s+result/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -30,40 +22,45 @@ assert.match(code, /bst\s*=\s*BinarySearchTree\(\s*\)/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -71,34 +68,46 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
--fcc-editable-region--
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 655a58897968829714d6e359
|
||||
id: 65ca120111bd521ea8b73e75
|
||||
title: Step 58
|
||||
challengeType: 20
|
||||
dashedName: step-58
|
||||
@@ -7,14 +7,14 @@ dashedName: step-58
|
||||
|
||||
# --description--
|
||||
|
||||
In the body of the `__str__` method, delete `pass` and return the result of calling the `str()` function with `self.key` as the argument. This is the attribute of the current node object that stores the value associated with the node.
|
||||
Now it's time to put everything into use. Uncomment the given line of code.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should return the string value of `self.key` from your `__str__` method.
|
||||
You should uncomment the `print('Search for 80:', bst.search(80))` line.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^\s{8}return\s+str\(\s*self\.key\s*\)/m) })
|
||||
assert.match(code, /^print\(\s*'Search\s*for\s*80:\s*',\s*bst\.search\(\s*80\s*\)\s*\)/m);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -22,44 +22,45 @@ You should return the string value of `self.key` from your `__str__` method.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
--fcc-editable-region--
|
||||
|
||||
def __str__(self):
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -67,42 +68,48 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
print("Inorder traversal:", bst.inorder_traversal())
|
||||
|
||||
print("Search for 40:", bst.search(40))
|
||||
--fcc-editable-region--
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
@@ -1,17 +1,17 @@
|
||||
---
|
||||
id: 655a57bf1d702b936f788b70
|
||||
title: Step 55
|
||||
id: 65ca294e05dc032bf8922dc7
|
||||
title: Step 59
|
||||
challengeType: 20
|
||||
dashedName: step-55
|
||||
dashedName: step-59
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Below the loop, call the `print()` function and pass it the string `Inorder traversal:` as the first argument and the `bst.inorder_traversal()` call as the second argument to print the result of the inorder traversal.
|
||||
Below the `print()` call, call the `print()` function again and pass it the string `'Inorder traversal:'` as the first argument and the `bst.inorder_traversal()` call as the second argument to print the result of the inorder traversal.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call `print()` and pass the string `Inorder traversal:` and the `bst.inorder_traversal()` call as the arguments.
|
||||
You should call `print()` and pass the string `'Inorder traversal:'` and the `bst.inorder_traversal()` call as the arguments.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /^print\s*\(\s*("|')Inorder traversal:\1\s*,\s*bst\.inorder_traversal\s*\(\s*\)\s*\)/m) })
|
||||
@@ -22,40 +22,45 @@ You should call `print()` and pass the string `Inorder traversal:` and the `bst.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -63,40 +68,47 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
--fcc-editable-region--
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
print('Search for 80:', bst.search(80))
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
```
|
||||
@@ -1,15 +1,13 @@
|
||||
---
|
||||
id: 655a58b2951601981fb893c8
|
||||
title: Step 59
|
||||
id: 65ca29b3a07d662de018ac13
|
||||
title: Step 60
|
||||
challengeType: 20
|
||||
dashedName: step-59
|
||||
dashedName: step-60
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
As you can see, now you get a readable output in the console.
|
||||
|
||||
After the `print()` calls, call the `delete` method of `bst` and delete `40` from the binary search tree.
|
||||
Next, call the `delete` method of `bst` and delete `40` from the binary search tree.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -24,7 +22,9 @@ You should call the `delete` method of `bst` passing `40` as the argument.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
@@ -34,33 +34,33 @@ class TreeNode:
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -68,33 +68,37 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
--fcc-editable-region--
|
||||
bst = BinarySearchTree()
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
@@ -102,8 +106,9 @@ nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
print("Inorder traversal:", bst.inorder_traversal())
|
||||
print("Search for 40:", bst.search(40))
|
||||
--fcc-editable-region--
|
||||
print('Search for 80:', bst.search(80))
|
||||
|
||||
print("Inorder traversal:", bst.inorder_traversal())
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,22 +1,23 @@
|
||||
---
|
||||
id: 655a585b87885d962f715a10
|
||||
title: Step 57
|
||||
id: 65ca2a18039c942f04ddde83
|
||||
title: Step 61
|
||||
challengeType: 20
|
||||
dashedName: step-57
|
||||
dashedName: step-61
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The result from the previous step is an object like this: `<__main__.TreeNode object at 0x7fecd9cc66b0>`. This is default string representation when printing an instance of a class.
|
||||
Confirm that `40` has been deleted.
|
||||
|
||||
To change that to print a useful value, define another method named `__str__` in the `TreeNode` class. It takes a single argument `self`.
|
||||
Call `print()` by passing the string `'Search for 40:'` as the first argument and an `bst.search(40)` call as the second argument.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should define a method `__str__` that takes a single argument `self`. Remember to use `pass`.
|
||||
You should have `print('Search for 40:', bst.search(40))` in your code.
|
||||
|
||||
|
||||
```js
|
||||
assert.match(code, /def\s+__str__\(\s*self\s*\)/);
|
||||
({ test: () => assert.match(code, /^print\(\s*("|')Search for 40:("|')\s*,\s*bst\.search\(\s*40\s*\)\s*\)/m) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -24,44 +25,45 @@ assert.match(code, /def\s+__str__\(\s*self\s*\)/);
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -69,42 +71,49 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
--fcc-editable-region--
|
||||
bst = BinarySearchTree()
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
print('Search for 80:', bst.search(80))
|
||||
|
||||
print("Inorder traversal:", bst.inorder_traversal())
|
||||
|
||||
print("Search for 40:", bst.search(40))
|
||||
bst.delete(40)
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -1,30 +1,36 @@
|
||||
---
|
||||
id: 655a59607b0d2e9b0f5d69e5
|
||||
title: Step 61
|
||||
id: 65ca2a52d579b22feb89177f
|
||||
title: Step 62
|
||||
challengeType: 20
|
||||
dashedName: step-61
|
||||
dashedName: step-62
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
As a last step, search for `40` again. It should be deleted. You can copy and paste the previous `print()` call.
|
||||
As a last step, print the whole tree.
|
||||
|
||||
Call `print()` by passing the string `'Inorder traversal after deleting 40:'` as the first argument and an `inorder_traversal()` call as the second argument.
|
||||
|
||||
With this, you have finished the implementation of the binary search tree. Great work!
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have `print('Search for 40:', bst.search(40))` at the bottom of your code.
|
||||
|
||||
You should call `print` passing the string `'Inorder traversal after deleting 40:'` as the first argument and an `inorder_traversal()` call as the second argument.
|
||||
|
||||
```js
|
||||
({ test: () => assert.equal(code.match(/^print\s*\(\s*("|')Search for 40:\1\s*,\s*bst\.search\s*\(\s*40\s*\)\s*\)/gm).length, 2) })
|
||||
({ test: () => assert.match(code, /^print\s*\(\s*("|')Inorder traversal after deleting 40:\1\s*,\s*bst\.inorder_traversal\s*\(\s*\)\s*\)/m) })
|
||||
```
|
||||
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
@@ -33,35 +39,34 @@ class TreeNode:
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -69,45 +74,51 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
return node
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
def _inorder_traversal(self, node, result):
|
||||
if node:
|
||||
self._inorder_traversal(node.left, result)
|
||||
result.append(node.key)
|
||||
self._inorder_traversal(node.right, result)
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
|
||||
--fcc-editable-region--
|
||||
bst = BinarySearchTree()
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
--fcc-editable-region--
|
||||
|
||||
print('Search for 80:', bst.search(80))
|
||||
|
||||
print("Inorder traversal:", bst.inorder_traversal())
|
||||
print("Search for 40:", bst.search(40))
|
||||
|
||||
bst.delete(40)
|
||||
print("Inorder traversal after deleting 40:", bst.inorder_traversal())
|
||||
|
||||
print("Search for 40:", bst.search(40))
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -200,7 +211,8 @@ print("Search for 40:", bst.search(40))
|
||||
|
||||
bst.delete(40)
|
||||
|
||||
print("Search for 40:", bst.search(40))
|
||||
|
||||
print("Inorder traversal after deleting 40:", bst.inorder_traversal())
|
||||
|
||||
print("Search for 40:", bst.search(40))
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a51ff908edc7c12c3a92c
|
||||
title: Step 41
|
||||
id: 65cb45d130c97cb459439fac
|
||||
title: Step 42
|
||||
challengeType: 20
|
||||
dashedName: step-41
|
||||
dashedName: step-42
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -13,6 +13,20 @@ To do this, write a `while` loop that runs when `node.left is not None` and move
|
||||
|
||||
# --hints--
|
||||
|
||||
you should remove the `pass` keyword from the `_min_value` method.
|
||||
|
||||
```js
|
||||
({
|
||||
test: () => {
|
||||
assert.isFalse(
|
||||
runPython(
|
||||
`_Node(_code).find_class("BinarySearchTree").find_function("_min_value").has_pass()`
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You should use the condition `node.left is not None` in the `while` loop.
|
||||
|
||||
```js
|
||||
@@ -24,40 +38,45 @@ You should use the condition `node.left is not None` in the `while` loop.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -65,20 +84,27 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
return node
|
||||
return node.left
|
||||
|
||||
--fcc-editable-region--
|
||||
def _min_value(self, node):
|
||||
pass
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a50f992ba7177aff2b718
|
||||
title: Step 38
|
||||
id: 65d8a6fcb15a3a239ba35dfd
|
||||
title: Step 46
|
||||
challengeType: 20
|
||||
dashedName: step-38
|
||||
dashedName: step-46
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -11,6 +11,8 @@ After finding the minimum value, you will need to recursively delete the node wi
|
||||
|
||||
This step ensures that the node with the minimum value is removed from the tree while maintaining the binary search tree (BST) property.
|
||||
|
||||
Call the `_delete` method recursively with `node.right` and `node.key` as the arguments. Assign the return value of the `_delete()` call to the right child of the current node.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call the `_delete` method recursively with `node.right` and `node.key` as the arguments.
|
||||
@@ -30,41 +32,47 @@ assert.match(code, /node\.right\s*=\s*self\._delete\(\s*node\.right\s*,\s*node\.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
@@ -77,7 +85,22 @@ class BinarySearchTree:
|
||||
return node.right
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
|
||||
--fcc-editable-region--
|
||||
node.key = self._min_value(node.right)
|
||||
--fcc-editable-region--
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a515f4b85ce79464fe5e8
|
||||
title: Step 39
|
||||
id: 65d8a8773c816a273653fd0e
|
||||
title: Step 47
|
||||
challengeType: 20
|
||||
dashedName: step-39
|
||||
dashedName: step-47
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -22,41 +22,47 @@ You should return the current node after the `else` clause.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
return node
|
||||
@@ -64,15 +70,28 @@ class BinarySearchTree:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
--fcc-editable-region--
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
|
||||
# bst = BinarySearchTree()
|
||||
|
||||
# nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
# for node in nodes:
|
||||
# bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 655a552337ee62882fdeee79
|
||||
id: 65d8a90640d40c2927ebbd94
|
||||
title: Step 48
|
||||
challengeType: 20
|
||||
dashedName: step-48
|
||||
@@ -7,14 +7,18 @@ dashedName: step-48
|
||||
|
||||
# --description--
|
||||
|
||||
Define the `_inorder_traversal` method and give it three parameters: `self`, `node` and `result`. Where `node` is the current node being considered during the traversal and `result` is the list to which the keys are appended in sorted order.
|
||||
Next, you'll work on the delete method.
|
||||
|
||||
Within the `BinarySearchTree` class, define a `delete` method. It takes two parameters: `self` and `key`.
|
||||
|
||||
`key` is the value that the user wants to delete from the binary search tree.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should define a method `_inorder_traversal` that takes three parameters: `self`, `node`, and `result`. Remember to use `pass`.
|
||||
You should define a `delete` method with two parameters: `self` and `key`. Remember to use `pass`.
|
||||
|
||||
```js
|
||||
assert.match(code, /def\s+_inorder_traversal\(\s*self\s*,\s*node\s*,\s*result\s*\)/);
|
||||
({ test: () => assert.match(code, /def\s+delete\(\s*self\s*,\s*key\s*\)/) });
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -22,40 +26,45 @@ assert.match(code, /def\s+_inorder_traversal\(\s*self\s*,\s*node\s*,\s*result\s*
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -70,7 +79,7 @@ class BinarySearchTree:
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
return node
|
||||
|
||||
@@ -78,12 +87,18 @@ class BinarySearchTree:
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
return node.key
|
||||
--fcc-editable-region--
|
||||
|
||||
def inorder_traversal(self):
|
||||
result = []
|
||||
self._inorder_traversal(self.root, result)
|
||||
return result
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 655a52bca925967fa2336190
|
||||
title: Step 43
|
||||
id: 65d8b58074495d3f94977dca
|
||||
title: Step 44
|
||||
challengeType: 20
|
||||
dashedName: step-43
|
||||
dashedName: step-44
|
||||
---
|
||||
|
||||
# --description--
|
||||
@@ -26,40 +26,45 @@ After the `while` loop, return `node.key` as the result of the function.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.key)
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def delete(self, key):
|
||||
self.root = self._delete(self.root, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def _delete(self, node, key):
|
||||
if node is None:
|
||||
@@ -67,21 +72,28 @@ class BinarySearchTree:
|
||||
if key < node.key:
|
||||
node.left = self._delete(node.left, key)
|
||||
elif key > node.key:
|
||||
node.right = self._delete(node.right, key)
|
||||
node.right = self._delete(node.right, key)
|
||||
else:
|
||||
if node.left is None:
|
||||
return node.right
|
||||
|
||||
elif node.right is None:
|
||||
return node.left
|
||||
|
||||
node.key = self._min_value(node.right)
|
||||
node.right = self._delete(node.right, node.key)
|
||||
return node
|
||||
|
||||
return node.left
|
||||
|
||||
--fcc-editable-region--
|
||||
def _min_value(self, node):
|
||||
while node.left is not None:
|
||||
node = node.left
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
bst = BinarySearchTree()
|
||||
|
||||
nodes = [50, 30, 20, 40, 70, 60, 80]
|
||||
|
||||
for node in nodes:
|
||||
bst.insert(node)
|
||||
|
||||
# print('Search for 80:', bst.search(80))
|
||||
|
||||
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 655a45c52fa3ea5ece3034c7
|
||||
id: 65f97131a0709033d6911558
|
||||
title: Step 27
|
||||
challengeType: 20
|
||||
dashedName: step-27
|
||||
@@ -7,14 +7,20 @@ dashedName: step-27
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the `delete` method, delete `pass` and call the private helper method `_delete` with the root of the binary search tree (BST) and the key to delete as the arguments.
|
||||
Create a list named `nodes` with values `50, 30, 20, 40, 70, 60, 80`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `delete` method should call the `_delete` method with two arguments: `self.root` and `key`.
|
||||
Your list should have the values `50, 30, 20, 40, 70, 60, 80`.
|
||||
|
||||
```js
|
||||
({ test: () => assert.match(code, /self\._delete\(\s*self\.root\s*,\s*key\s*\)/) });
|
||||
assert.match(code, /\s*\[50,\s*30,\s*20,\s*40,\s*70,\s*60,\s*80\]/);
|
||||
```
|
||||
|
||||
Your list should be assigned to nodes.
|
||||
|
||||
```js
|
||||
assert.match(code, /nodes\s*=\s*\[50,\s*30,\s*20,\s*40,\s*70,\s*60,\s*80\]/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
@@ -22,40 +28,47 @@ Your `delete` method should call the `_delete` method with two arguments: `self.
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
|
||||
class TreeNode:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
self.left = None
|
||||
self.right = None
|
||||
|
||||
|
||||
class BinarySearchTree:
|
||||
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
|
||||
def insert(self,key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _insert(self, node, key):
|
||||
if node is None:
|
||||
return TreeNode(key)
|
||||
|
||||
if key < node.key:
|
||||
node.left = self._insert(node.left, key)
|
||||
elif key > node.key:
|
||||
|
||||
node.right = self._insert(node.right, key)
|
||||
return node
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
def insert(self, key):
|
||||
self.root = self._insert(self.root, key)
|
||||
|
||||
def _search(self, node, key):
|
||||
if node is None or node.key == key:
|
||||
return node
|
||||
if key < node.key:
|
||||
return self._search(node.left, key)
|
||||
return self._search(node.right, key)
|
||||
|
||||
def search(self, key):
|
||||
return self._search(self.root, key)
|
||||
|
||||
--fcc-editable-region--
|
||||
def delete(self, key):
|
||||
pass
|
||||
bst = BinarySearchTree()
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
Reference in New Issue
Block a user