-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_binary_tree.py
More file actions
287 lines (227 loc) · 8.98 KB
/
Copy pathtest_binary_tree.py
File metadata and controls
287 lines (227 loc) · 8.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
"""
Unit Tests for Binary Tree Module
This file contains comprehensive unit tests for the binary tree implementations
to ensure correctness of operations, traversals, and balancing.
Author: Python Study Repository
"""
import unittest
import sys
import os
# Add the binary-tree directory to path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from binary_tree import TreeNode, BinaryTree
from balanced_tree import AVLTree, RedBlackTree
class TestBinaryTree(unittest.TestCase):
"""Test cases for basic Binary Search Tree."""
def setUp(self):
"""Set up a test tree before each test."""
self.tree = BinaryTree()
self.values = [10, 5, 15, 3, 7, 12, 18]
for val in self.values:
self.tree.insert(val)
def test_insert(self):
"""Test insertion creates correct structure."""
tree = BinaryTree()
tree.insert(10)
self.assertEqual(tree.root.val, 10)
tree.insert(5)
self.assertEqual(tree.root.left.val, 5)
tree.insert(15)
self.assertEqual(tree.root.right.val, 15)
def test_search_existing(self):
"""Test searching for existing values."""
for val in self.values:
self.assertTrue(self.tree.search(val))
def test_search_non_existing(self):
"""Test searching for non-existing values."""
self.assertFalse(self.tree.search(100))
self.assertFalse(self.tree.search(-5))
def test_inorder_traversal(self):
"""Test inorder traversal returns sorted values."""
result = self.tree.inorder()
expected = sorted(self.values)
self.assertEqual(result, expected)
def test_preorder_traversal(self):
"""Test preorder traversal."""
result = self.tree.preorder()
# Root should be first
self.assertEqual(result[0], 10)
# Should contain all values
self.assertEqual(sorted(result), sorted(self.values))
def test_postorder_traversal(self):
"""Test postorder traversal."""
result = self.tree.postorder()
# Root should be last
self.assertEqual(result[-1], 10)
# Should contain all values
self.assertEqual(sorted(result), sorted(self.values))
def test_level_order_traversal(self):
"""Test level-order traversal."""
result = self.tree.level_order()
# Root should be first
self.assertEqual(result[0], 10)
# Should contain all values
self.assertEqual(sorted(result), sorted(self.values))
def test_height(self):
"""Test height calculation."""
# Tree with 7 nodes should have height 3
self.assertEqual(self.tree.height(), 3)
# Empty tree
empty_tree = BinaryTree()
self.assertEqual(empty_tree.height(), 0)
# Single node
single_tree = BinaryTree()
single_tree.insert(10)
self.assertEqual(single_tree.height(), 1)
def test_is_balanced(self):
"""Test balance checking."""
self.assertTrue(self.tree.is_balanced())
# Create unbalanced tree
unbalanced = BinaryTree()
for i in range(1, 6):
unbalanced.insert(i)
self.assertFalse(unbalanced.is_balanced())
def test_balance_factor(self):
"""Test balance factor calculation."""
bf = self.tree.balance_factor(self.tree.root)
self.assertIn(bf, [-1, 0, 1]) # Balanced tree should have BF in {-1, 0, 1}
def test_size(self):
"""Test size calculation."""
self.assertEqual(self.tree.size(), len(self.values))
empty_tree = BinaryTree()
self.assertEqual(empty_tree.size(), 0)
def test_min_max(self):
"""Test min and max value finding."""
self.assertEqual(self.tree.min_value(), min(self.values))
self.assertEqual(self.tree.max_value(), max(self.values))
class TestAVLTree(unittest.TestCase):
"""Test cases for AVL Tree (self-balancing)."""
def test_avl_always_balanced(self):
"""Test that AVL tree maintains balance after insertions."""
avl = AVLTree()
# Insert sequential values (worst case for regular BST)
for i in range(1, 16):
avl.insert(i)
self.assertTrue(avl.is_balanced())
# Height should be O(log n)
self.assertLessEqual(avl.height(), 5) # log2(15) ≈ 4
def test_avl_rotations_left_left(self):
"""Test Left-Left case triggers right rotation."""
avl = AVLTree()
avl.insert(30)
avl.insert(20)
avl.insert(10)
# After rotation, 20 should be root
self.assertEqual(avl.root.val, 20)
self.assertEqual(avl.root.left.val, 10)
self.assertEqual(avl.root.right.val, 30)
def test_avl_rotations_right_right(self):
"""Test Right-Right case triggers left rotation."""
avl = AVLTree()
avl.insert(10)
avl.insert(20)
avl.insert(30)
# After rotation, 20 should be root
self.assertEqual(avl.root.val, 20)
self.assertEqual(avl.root.left.val, 10)
self.assertEqual(avl.root.right.val, 30)
def test_avl_rotations_left_right(self):
"""Test Left-Right case triggers left-right rotation."""
avl = AVLTree()
avl.insert(30)
avl.insert(10)
avl.insert(20)
# After rotation, 20 should be root
self.assertEqual(avl.root.val, 20)
self.assertEqual(avl.root.left.val, 10)
self.assertEqual(avl.root.right.val, 30)
def test_avl_rotations_right_left(self):
"""Test Right-Left case triggers right-left rotation."""
avl = AVLTree()
avl.insert(10)
avl.insert(30)
avl.insert(20)
# After rotation, 20 should be root
self.assertEqual(avl.root.val, 20)
self.assertEqual(avl.root.left.val, 10)
self.assertEqual(avl.root.right.val, 30)
def test_avl_inorder_sorted(self):
"""Test AVL tree maintains BST property."""
avl = AVLTree()
values = [50, 30, 70, 20, 40, 60, 80]
for val in values:
avl.insert(val)
result = avl.inorder()
self.assertEqual(result, sorted(values))
def test_avl_search(self):
"""Test AVL tree search operation."""
avl = AVLTree()
values = [10, 20, 30, 40, 50]
for val in values:
avl.insert(val)
for val in values:
self.assertTrue(avl.search(val))
self.assertFalse(avl.search(100))
class TestRedBlackTree(unittest.TestCase):
"""Test cases for Red-Black Tree."""
def test_rb_tree_insert(self):
"""Test Red-Black tree insertion."""
rb = RedBlackTree()
values = [10, 20, 30, 15, 25, 5]
for val in values:
rb.insert(val)
# Check inorder traversal is sorted
result = rb.inorder()
self.assertEqual(result, sorted(values))
def test_rb_tree_root_is_black(self):
"""Test that root is always black."""
rb = RedBlackTree()
rb.insert(10)
self.assertEqual(rb.root.color, 'BLACK')
rb.insert(20)
self.assertEqual(rb.root.color, 'BLACK')
def test_rb_tree_inorder(self):
"""Test Red-Black tree maintains BST property."""
rb = RedBlackTree()
values = [10, 20, 30, 15, 25, 5, 1, 35, 40]
for val in values:
rb.insert(val)
result = rb.inorder()
self.assertEqual(result, sorted(values))
class TestTreeComparison(unittest.TestCase):
"""Test cases comparing different tree implementations."""
def test_height_comparison(self):
"""Compare heights of balanced vs unbalanced trees."""
# Unbalanced tree (sequential insertion)
unbalanced = BinaryTree()
for i in range(1, 16):
unbalanced.insert(i)
# AVL tree (same values)
avl = AVLTree()
for i in range(1, 16):
avl.insert(i)
# AVL should have significantly smaller height
self.assertLess(avl.height(), unbalanced.height())
# AVL height should be O(log n)
self.assertLessEqual(avl.height(), 5) # log2(15) ≈ 4
def test_all_trees_maintain_bst_property(self):
"""Test that all tree types maintain BST property."""
values = [50, 30, 70, 20, 40, 60, 80]
# Binary Tree
bt = BinaryTree()
for val in values:
bt.insert(val)
self.assertEqual(bt.inorder(), sorted(values))
# AVL Tree
avl = AVLTree()
for val in values:
avl.insert(val)
self.assertEqual(avl.inorder(), sorted(values))
# Red-Black Tree
rb = RedBlackTree()
for val in values:
rb.insert(val)
self.assertEqual(rb.inorder(), sorted(values))
if __name__ == '__main__':
# Run tests with verbose output
unittest.main(verbosity=2)