Skip to content

Commit f236ea1

Browse files
rodrigocamNathan Parsons
authored and
Nathan Parsons
committed
Implement exercise binary-search-tree (#773)
1 parent 16ba6f5 commit f236ea1

File tree

5 files changed

+218
-0
lines changed

5 files changed

+218
-0
lines changed

config.json

+14
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,20 @@
12001200
"reactive_programming"
12011201
]
12021202
},
1203+
{
1204+
"uuid": "6f196341-0ffc-9780-a7ca-1f817508247161cbcd9",
1205+
"slug": "binary-search-tree",
1206+
"core": false,
1207+
"unlocked_by": null,
1208+
"difficulty": 4,
1209+
"topics":[
1210+
"recursion",
1211+
"classes",
1212+
"trees",
1213+
"searching",
1214+
"object_oriented_programming"
1215+
]
1216+
},
12031217
{
12041218
"uuid": "e7351e8e-d3ff-4621-b818-cd55cf05bffd",
12051219
"slug": "accumulate",
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Binary Search Tree
2+
3+
Insert and search for numbers in a binary tree.
4+
5+
When we need to represent sorted data, an array does not make a good
6+
data structure.
7+
8+
Say we have the array `[1, 3, 4, 5]`, and we add 2 to it so it becomes
9+
`[1, 3, 4, 5, 2]` now we must sort the entire array again! We can
10+
improve on this by realizing that we only need to make space for the new
11+
item `[1, nil, 3, 4, 5]`, and then adding the item in the space we
12+
added. But this still requires us to shift many elements down by one.
13+
14+
Binary Search Trees, however, can operate on sorted data much more
15+
efficiently.
16+
17+
A binary search tree consists of a series of connected nodes. Each node
18+
contains a piece of data (e.g. the number 3), a variable named `left`,
19+
and a variable named `right`. The `left` and `right` variables point at
20+
`nil`, or other nodes. Since these other nodes in turn have other nodes
21+
beneath them, we say that the left and right variables are pointing at
22+
subtrees. All data in the left subtree is less than or equal to the
23+
current node's data, and all data in the right subtree is greater than
24+
the current node's data.
25+
26+
For example, if we had a node containing the data 4, and we added the
27+
data 2, our tree would look like this:
28+
29+
4
30+
/
31+
2
32+
33+
If we then added 6, it would look like this:
34+
35+
4
36+
/ \
37+
2 6
38+
39+
If we then added 3, it would look like this
40+
41+
4
42+
/ \
43+
2 6
44+
\
45+
3
46+
47+
And if we then added 1, 5, and 7, it would look like this
48+
49+
4
50+
/ \
51+
/ \
52+
2 6
53+
/ \ / \
54+
1 3 5 7
55+
56+
57+
## Submitting Exercises
58+
59+
Note that, when trying to submit an exercise, make sure the solution is in the `exercism/python/<exerciseName>` directory.
60+
61+
For example, if you're submitting `bob.py` for the Bob exercise, the submit command would be something like `exercism submit <path_to_exercism_dir>/python/bob/bob.py`.
62+
63+
For more detailed information about running tests, code style and linting,
64+
please see the [help page](http://exercism.io/languages/python).
65+
66+
## Source
67+
68+
Wikipedia [https://en.wikipedia.org/wiki/Binary_search_tree](https://en.wikipedia.org/wiki/Binary_search_tree)
69+
70+
## Submitting Incomplete Solutions
71+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class TreeNode(object):
2+
def __init__(self, value):
3+
self.value = value
4+
5+
6+
class BinarySearchTree(object):
7+
def __init__(self):
8+
pass
9+
10+
def add(self, value):
11+
pass
12+
13+
def search(self, value):
14+
pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import unittest
2+
3+
from binary_search_tree import BinarySearchTree
4+
5+
6+
class BinarySearchTreeTests(unittest.TestCase):
7+
8+
def test_add_integer_numbers(self):
9+
bst = BinarySearchTree()
10+
bst.add(1)
11+
bst.add(8)
12+
bst.add(3)
13+
bst.add(5)
14+
bst.add(2)
15+
self.assertEqual(list(bst.list()), [1, 2, 3, 5, 8])
16+
17+
def test_add_float_numbers(self):
18+
bst = BinarySearchTree()
19+
bst.add(7.5)
20+
bst.add(5.3)
21+
bst.add(5.5)
22+
bst.add(6.0)
23+
bst.add(7.7)
24+
self.assertEqual(list(bst.list()), [5.3, 5.5, 6.0, 7.5, 7.7])
25+
26+
def test_add_mixed_numbers(self):
27+
bst = BinarySearchTree()
28+
bst.add(1)
29+
bst.add(8)
30+
bst.add(7.5)
31+
bst.add(5.3)
32+
self.assertEqual(list(bst.list()), [1, 5.3, 7.5, 8])
33+
34+
def test_add_duplicated_numbers(self):
35+
bst = BinarySearchTree()
36+
bst.add(1)
37+
bst.add(1)
38+
bst.add(7.5)
39+
bst.add(5.3)
40+
self.assertEqual(list(bst.list()), [1, 1, 5.3, 7.5])
41+
42+
def test_search_existent_numbers(self):
43+
bst = BinarySearchTree()
44+
bst.add(1)
45+
bst.add(7.5)
46+
self.assertEqual(bst.search(1).value, 1)
47+
self.assertEqual(bst.search(7.5).value, 7.5)
48+
49+
def test_search_nonexistent_numbers(self):
50+
bst = BinarySearchTree()
51+
bst.add(1)
52+
bst.add(7.5)
53+
self.assertIs(bst.search(6), None)
54+
self.assertIs(bst.search(8.8), None)
55+
56+
57+
if __name__ == '__main__':
58+
unittest.main()
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from collections import deque
2+
3+
4+
class TreeNode(object):
5+
def __init__(self, value):
6+
self.value = value
7+
self.left_node = None
8+
self.right_node = None
9+
10+
def __str__(self):
11+
return str(self.value)
12+
13+
14+
class BinarySearchTree(object):
15+
def __init__(self):
16+
self.root = None
17+
18+
def add(self, value):
19+
if(self.root is None):
20+
self.root = TreeNode(value)
21+
else:
22+
inserted = False
23+
cur_node = self.root
24+
25+
while not inserted:
26+
if(value <= cur_node.value):
27+
if(cur_node.left_node):
28+
cur_node = cur_node.left_node
29+
else:
30+
cur_node.left_node = TreeNode(value)
31+
inserted = True
32+
elif(value > cur_node.value):
33+
if(cur_node.right_node):
34+
cur_node = cur_node.right_node
35+
else:
36+
cur_node.right_node = TreeNode(value)
37+
inserted = True
38+
39+
def search(self, value):
40+
cur_node = self.root
41+
found = False
42+
while not found:
43+
if(cur_node is None):
44+
return None
45+
elif(value < cur_node.value):
46+
cur_node = cur_node.left_node
47+
elif(value > cur_node.value):
48+
cur_node = cur_node.right_node
49+
elif(value == cur_node.value):
50+
return cur_node
51+
52+
def list(self):
53+
elements = deque()
54+
self.trav_inorder(self.root, elements)
55+
return elements
56+
57+
def trav_inorder(self, node, elements):
58+
if(node is not None):
59+
self.trav_inorder(node.left_node, elements)
60+
elements.append(node.value)
61+
self.trav_inorder(node.right_node, elements)

0 commit comments

Comments
 (0)