1- r"""
2- A binary search Tree
3-
4- Example
5- 8
6- / \
7- 3 10
8- / \ \
9- 1 6 14
10- / \ /
11- 4 7 13
12-
13- >>> t = BinarySearchTree().insert(8, 3, 6, 1, 10, 14, 13, 4, 7)
14- >>> print(" ".join(repr(i.value) for i in t.traversal_tree()))
15- 8 3 1 6 4 7 10 14 13
16-
17- >>> tuple(i.value for i in t.traversal_tree(inorder))
18- (1, 3, 4, 6, 7, 8, 10, 13, 14)
19- >>> tuple(t)
20- (1, 3, 4, 6, 7, 8, 10, 13, 14)
21- >>> t.find_kth_smallest(3, t.root)
22- 4
23- >>> tuple(t)[3-1]
24- 4
25-
26- >>> print(" ".join(repr(i.value) for i in t.traversal_tree(postorder)))
27- 1 4 7 6 3 13 14 10 8
28- >>> t.remove(20)
29- Traceback (most recent call last):
30- ...
31- ValueError: Value 20 not found
32- >>> BinarySearchTree().search(6)
33- Traceback (most recent call last):
34- ...
35- IndexError: Warning: Tree is empty! please use another.
36-
37- Other example:
38-
39- >>> testlist = (8, 3, 6, 1, 10, 14, 13, 4, 7)
40- >>> t = BinarySearchTree()
41- >>> for i in testlist:
42- ... t.insert(i) # doctest: +ELLIPSIS
43- BinarySearchTree(root=8)
44- BinarySearchTree(root={'8': (3, None)})
45- BinarySearchTree(root={'8': ({'3': (None, 6)}, None)})
46- BinarySearchTree(root={'8': ({'3': (1, 6)}, None)})
47- BinarySearchTree(root={'8': ({'3': (1, 6)}, 10)})
48- BinarySearchTree(root={'8': ({'3': (1, 6)}, {'10': (None, 14)})})
49- BinarySearchTree(root={'8': ({'3': (1, 6)}, {'10': (None, {'14': (13, None)})})})
50- BinarySearchTree(root={'8': ({'3': (1, {'6': (4, None)})}, {'10': (None, {'14': ...
51- BinarySearchTree(root={'8': ({'3': (1, {'6': (4, 7)})}, {'10': (None, {'14': (13, ...
52-
53- Prints all the elements of the list in order traversal
54- >>> print(t)
55- {'8': ({'3': (1, {'6': (4, 7)})}, {'10': (None, {'14': (13, None)})})}
56-
57- Test existence
58- >>> t.search(6) is not None
59- True
60- >>> 6 in t
61- True
62- >>> t.search(-1) is not None
63- False
64- >>> -1 in t
65- False
66-
67- >>> t.search(6).is_right
68- True
69- >>> t.search(1).is_right
70- False
71-
72- >>> t.get_max().value
73- 14
74- >>> max(t)
75- 14
76- >>> t.get_min().value
77- 1
78- >>> min(t)
79- 1
80- >>> t.empty()
81- False
82- >>> not t
83- False
84- >>> for i in testlist:
85- ... t.remove(i)
86- >>> t.empty()
87- True
88- >>> not t
89- True
90- """
911from __future__ import annotations
92- from pprint import pformat # Moved to top-level
2+ from pprint import pformat
933from collections .abc import Iterable , Iterator
944from dataclasses import dataclass
955from typing import Any , Self
966
97-
987@dataclass
998class Node :
1009 value : int
10110 left : Node | None = None
10211 right : Node | None = None
103- parent : Node | None = None # Added in order to delete a node easier
104-
105- def __iter__ (self ) -> Iterator [int ]:
106- """
107- >>> list(Node(0))
108- [0]
109- >>> list(Node(0, Node(-1), Node(1), None))
110- [-1, 0, 1]
111- """
112- yield from self .left or []
113- yield self .value
114- yield from self .right or []
12+ parent : Node | None = None
11513
11614 def __repr__ (self ) -> str :
11715 if self .left is None and self .right is None :
11816 return str (self .value )
11917 return pformat ({f"{ self .value } " : (self .left , self .right )}, indent = 1 )
12018
121- @property
122- def is_right (self ) -> bool :
123- return bool (self .parent and self is self .parent .right )
124-
125-
12619@dataclass
12720class BinarySearchTree :
12821 root : Node | None = None
12922
130- def __bool__ (self ) -> bool :
131- return bool (self .root )
132-
133- def __iter__ (self ) -> Iterator [int ]:
134- yield from self .root or []
135-
136- def __str__ (self ) -> str :
137- """
138- Return a string of all the Nodes using in order traversal
139- """
140- return str (self .root )
141-
14223 def __reassign_nodes (self , node : Node , new_children : Node | None ) -> None :
143- if new_children is not None : # reset its kids
24+ if new_children is not None :
14425 new_children .parent = node .parent
145- if node .parent is not None : # reset its parent
146- if node .is_right : # If it is the right child
26+ if node .parent is not None :
27+ if node .is_right :
14728 node .parent .right = new_children
14829 else :
14930 node .parent .left = new_children
15031 else :
15132 self .root = new_children
15233
153- def empty (self ) -> bool :
154- """
155- Returns True if the tree does not have any element(s).
156- False if the tree has element(s).
157-
158- >>> BinarySearchTree().empty()
159- True
160- >>> BinarySearchTree().insert(1).empty()
161- False
162- >>> BinarySearchTree().insert(8, 3, 6, 1, 10, 14, 13, 4, 7).empty()
163- False
164- """
165- return not self .root
166-
16734 def __insert (self , value ) -> None :
168- """
169- Insert a new node in Binary Search Tree with value label
170- """
171- new_node = Node (value ) # create a new Node
172- if self .empty (): # if Tree is empty
173- self .root = new_node # set its root
174- else : # Tree is not empty
175- parent_node = self .root # from root
176- if parent_node is None :
177- return
178- while True : # While we don't get to a leaf
179- if value < parent_node .value : # We go left
35+ new_node = Node (value )
36+ if self .empty ():
37+ self .root = new_node
38+ else :
39+ parent_node = self .root
40+ while True :
41+ if value < parent_node .value :
18042 if parent_node .left is None :
181- parent_node .left = new_node # We insert the new node in a leaf
43+ parent_node .left = new_node
18244 break
18345 else :
18446 parent_node = parent_node .left
@@ -189,163 +51,43 @@ def __insert(self, value) -> None:
18951 parent_node = parent_node .right
19052 new_node .parent = parent_node
19153
192- def insert (self , * values ) -> Self :
193- for value in values :
194- self .__insert (value )
195- return self
196- def search (self , value ) -> Node | None :
197- """
198- >>> tree = BinarySearchTree().insert(10, 20, 30, 40, 50)
199- >>> tree.search(10)
200- {'10': (None, {'20': (None, {'30': (None, {'40': (None, 50)})})}
201- >>> tree.search(20)
202- {'20': (None, {'30': (None, {'40': (None, 50)})})}
203- >>> tree.search(30)
204- {'30': (None, {'40': (None, 50)})}
205- >>> tree.search(40)
206- {'40': (None, 50)}
207- >>> tree.search(50)
208- 50
209- >>> tree.search(5) is None # element not present
210- True
211- >>> tree.search(0) is None # element not present
212- True
213- >>> tree.search(-5) is None # element not present
214- True
215- >>> BinarySearchTree().search(10)
216- Traceback (most recent call last):
217- ...
218- IndexError: Warning: Tree is empty! please use another.
219- """
220-
54+ def search (self , value ) -> Node | None :
22155 if self .empty ():
22256 raise IndexError ("Warning: Tree is empty! please use another." )
223- else :
224- node = self .root
225- # use lazy evaluation here to avoid NoneType Attribute error
226- while node is not None and node .value is not value :
227- node = node .left if value < node .value else node .right
228- return node
229-
230- def get_max (self , node : Node | None = None ) -> Node | None :
231- """
232- We go deep on the right branch
233-
234- >>> BinarySearchTree().insert(10, 20, 30, 40, 50).get_max()
235- 50
236- >>> BinarySearchTree().insert(-5, -1, 0.1, -0.3, -4.5).get_max()
237- {'0.1': (-0.3, None)}
238- >>> BinarySearchTree().insert(1, 78.3, 30, 74.0, 1).get_max()
239- {'78.3': ({'30': (1, 74.0)}, None)}
240- >>> BinarySearchTree().insert(1, 783, 30, 740, 1).get_max()
241- {'783': ({'30': (1, 740)}, None)}
242- """
243- if node is None :
244- if self .root is None :
245- return None
246- node = self .root
247-
248- if not self .empty ():
249- while node .right is not None :
250- node = node .right
251- return node
252-
253- def get_min (self , node : Node | None = None ) -> Node | None :
254- """
255- We go deep on the left branch
256-
257- >>> BinarySearchTree().insert(10, 20, 30, 40, 50).get_min()
258- {'10': (None, {'20': (None, {'30': (None, {'40': (None, 50)})})})}
259- >>> BinarySearchTree().insert(-5, -1, 0, -0.3, -4.5).get_min()
260- {'-5': (None, {'-1': (-4.5, {'0': (-0.3, None)})})}
261- >>> BinarySearchTree().insert(1, 78.3, 30, 74.0, 1).get_min()
262- {'1': (None, {'78.3': ({'30': (1, 74.0)}, None)})}
263- >>> BinarySearchTree().insert(1, 783, 30, 740, 1).get_min()
264- {'1': (None, {'783': ({'30': (1, 740)}, None)})}
265- """
266- if node is None :
267- node = self .root
268- if self .root is None :
269- return None
270- if not self .empty ():
271- node = self .root
272- while node .left is not None :
273- node = node .left
57+ node = self .root
58+ while node is not None and node .value != value :
59+ node = node .left if value < node .value else node .right
27460 return node
27561
27662 def remove (self , value : int ) -> None :
277- # Look for the node with that label
27863 node = self .search (value )
27964 if node is None :
280- msg = f"Value { value } not found"
281- raise ValueError (msg )
65+ raise ValueError (f"Value { value } not found" )
28266
283- if node .left is None and node .right is None : # If it has no children
67+ if node .left is None and node .right is None :
28468 self .__reassign_nodes (node , None )
285- elif node .left is None : # Has only right children
69+ elif node .left is None :
28670 self .__reassign_nodes (node , node .right )
287- elif node .right is None : # Has only left children
71+ elif node .right is None :
28872 self .__reassign_nodes (node , node .left )
28973 else :
290- predecessor = self .get_max (
291- node .left
292- ) # Gets the max value of the left branch
293- self .remove (predecessor .value ) # type: ignore[union-attr]
294- node .value = (
295- predecessor .value # type: ignore[union-attr]
296- ) # Assigns the value to the node to delete and keep tree structure
297-
298- def preorder_traverse (self , node : Node | None ) -> Iterable :
299- if node is not None :
300- yield node # Preorder Traversal
301- yield from self .preorder_traverse (node .left )
302- yield from self .preorder_traverse (node .right )
303-
304- def traversal_tree (self , traversal_function = None ) -> Any :
305- """
306- This function traversal the tree.
307- You can pass a function to traversal the tree as needed by client code
308- """
309- if traversal_function is None :
310- return self .preorder_traverse (self .root )
311- else :
312- return traversal_function (self .root )
313- def inorder (self , arr : list , node : Node | None ) -> None :
314- """Perform an inorder traversal and append values of the nodes to
315- a list named arr"""
316- if node :
317- self .inorder (arr , node .left )
318- arr .append (node .value )
319- self .inorder (arr , node .right )
320-
321- def find_kth_smallest (self , k : int , node : Node ) -> int :
322- """Return the kth smallest element in a binary search tree"""
323- arr : list [int ] = []
324- self .inorder (arr , node ) # append all values to list using inorder traversal
325- return arr [k - 1 ]
326-
74+ predecessor = self .get_max (node .left )
75+ self .remove (predecessor .value )
76+ node .value = predecessor .value
32777
78+ # 修复的递归函数
32879def inorder (curr_node : Node | None ) -> list [Node ]:
329- """
330- inorder (left, self, right)
331- """
332- node_list = []
333- if curr_node is not None :
334- node_list = [* inorder (curr_node .left ), curr_node , * inorder (curr_node .right )]
335- return node_list
336-
80+ """Inorder traversal (left, self, right)"""
81+ if curr_node is None :
82+ return []
83+ return inorder (curr_node .left ) + [curr_node ] + inorder (curr_node .right )
33784
33885def postorder (curr_node : Node | None ) -> list [Node ]:
339- """
340- postOrder (left, right, self)
341- """
342- node_list = []
343- if curr_node is not None :
344- node_list = postorder (curr_node .left ) + postorder (curr_node .right ) + [curr_node ]
345- return node_list
346-
86+ """Postorder traversal (left, right, self)"""
87+ if curr_node is None :
88+ return []
89+ return postorder (curr_node .left ) + postorder (curr_node .right ) + [curr_node ]
34790
34891if __name__ == "__main__" :
34992 import doctest
350-
35193 doctest .testmod (verbose = True )
0 commit comments