-
Notifications
You must be signed in to change notification settings - Fork 181
/
Copy pathbst_demo.py
139 lines (124 loc) · 4.78 KB
/
bst_demo.py
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
from datetime import datetime, timedelta
class Node:
def __init__(self, key):
sched_time, duration, name_of_job = key.split(",")
raw_sched_time = datetime.strptime(sched_time, '%H:%M')
key = raw_sched_time.time()
end_time = (raw_sched_time + timedelta(minutes=int(duration))).time()
self.data = key
self.scheduled_end = end_time
self.duration = duration
self.name_of_job = name_of_job.rstrip()
self.left_child = None
self.right_child = None
def __str__(self):
return f"Time: {self.data}, Duration: {self.duration}, End: {self.scheduled_end}, Jobname: {self.name_of_job}"
class BSTDemo:
def __init__(self):
self.root = None
def insert(self, key):
if not isinstance(key, Node):
key = Node(key)
if self.root == None:
self.root = key
self.helpful_print(key, True)
else:
self._insert(self.root, key)
def _insert(self, curr, key):
if key.data > curr.data and key.data >= curr.scheduled_end:
if curr.right_child == None:
curr.right_child = key
self.helpful_print(key, True)
else:
self._insert(curr.right_child, key)
elif key.data < curr.data and key.scheduled_end <= curr.data:
if curr.left_child == None:
curr.left_child = key
self.helpful_print(key, True)
else:
self._insert(curr.left_child, key)
else:
self.helpful_print(key, False)
def helpful_print(self, key, succeeded):
if succeeded:
print(f"Added:\t\t {key.name_of_job}")
print(f"Begin:\t\t {key.data}")
print(f"End:\t\t {key.scheduled_end}")
print("-"*60)
else:
print(f"Rejected:\t {key.name_of_job}")
print(f"Begin:\t\t {key.data}")
print(f"End:\t\t {key.scheduled_end}")
print("Reason:\t Time slot overlap, please verify")
print("-"*60)
def in_order(self):
print("Full job schedule for today")
print("-"*60)
self._in_order(self.root)
print("-"*60)
def _in_order(self, curr):
if curr:
self._in_order(curr.left_child)
print(curr)
self._in_order(curr.right_child)
def length(self):
return self._length(self.root)
def _length(self, curr):
if curr is None:
return 0
return 1 + self._length(curr.left_child) + self._length(curr.right_child)
def find_val(self, key):
return self._find_val(self.root, key)
def _find_val(self, curr, key):
if curr:
if key == curr.data:
return curr
elif key < curr.data:
return self._find_val(curr.left_child, key)
else:
return self._find_val(curr.right_child, key)
return
def min_right_subtree(self, curr):
if curr.left_child == None:
return curr
else:
return self.min_right_subtree(curr.left_child)
def delete_val(self, key):
self._delete_val(self.root, None, None, key)
def _delete_val(self, curr, prev, is_left, key):
if curr:
if key == curr.data:
if curr.left_child and curr.right_child:
min_child = self.min_right_subtree(curr.right_child)
curr.data = min_child.data
self._delete_val(curr.right_child, curr, False, min_child.data)
elif curr.left_child == None and curr.right_child == None:
if prev:
if is_left:
prev.left_child = None
else:
prev.right_child = None
else:
self.root = None
elif curr.left_child == None:
if prev:
if is_left:
prev.left_child = curr.right_child
else:
prev.right_child = curr.right_child
else:
self.root = curr.right_child
else:
if prev:
if is_left:
prev.left_child = curr.left_child
else:
prev.right_child = curr.left_child
else:
self.root = curr.left_child
elif key < curr.data:
self._delete_val(curr.left_child, curr, True, key)
elif key > curr.data:
self._delete_val(curr.right_child, curr, False, key)
else:
print(f"{key} not found in Tree")