-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDANCING Tree.py
More file actions
126 lines (112 loc) · 4.05 KB
/
DANCING Tree.py
File metadata and controls
126 lines (112 loc) · 4.05 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
class DancingTreeNode:
def __init__(self, t):
self.t = t # Minimum degree
self.keys = [] # Keys in the node
self.children = [] # Child pointers
self.leaf = True # Is this a leaf node?
def is_full(self):
return len(self.keys) == 2 * self.t - 1
def insert_non_full(self, key):
i = len(self.keys) - 1
if self.leaf:
# Insert the key into the correct position
self.keys.append(None)
while i >= 0 and key < self.keys[i]:
self.keys[i + 1] = self.keys[i]
i -= 1
self.keys[i + 1] = key
else:
# Find the child to insert the key into
while i >= 0 and key < self.keys[i]:
i -= 1
i += 1
if self.children[i].is_full():
self.split_child(i)
if key > self.keys[i]:
i += 1
self.children[i].insert_non_full(key)
def split_child(self, i):
t = self.t
child = self.children[i]
new_child = DancingTreeNode(t)
new_child.leaf = child.leaf
self.children.insert(i + 1, new_child)
self.keys.insert(i, child.keys[t - 1])
new_child.keys = child.keys[t:]
child.keys = child.keys[:t - 1]
if not child.leaf:
new_child.children = child.children[t:]
child.children = child.children[:t]
class DancingTree:
def __init__(self, t):
self.t = t # Minimum degree
self.root = DancingTreeNode(t)
def insert(self, key):
root = self.root
if root.is_full():
new_root = DancingTreeNode(self.t)
self.root = new_root
new_root.leaf = False
new_root.children.append(root)
new_root.split_child(0)
new_root.insert_non_full(key)
else:
root.insert_non_full(key)
def traverse(self, node=None):
if node is None:
node = self.root
for i, key in enumerate(node.keys):
if not node.leaf:
self.traverse(node.children[i])
print(key, end=" ")
if not node.leaf:
self.traverse(node.children[-1])
def search(self, key, node=None):
if node is None:
node = self.root
i = 0
while i < len(node.keys) and key > node.keys[i]:
i += 1
if i < len(node.keys) and key == node.keys[i]:
return True
if node.leaf:
return False
return self.search(key, node.children[i])
def delete(self, key):
# Deletion in a Dancing Tree involves handling cases of underflow and merging.
# For simplicity, deletion here just marks the node as unbalanced.
print(f"Deletion of {key} is not fully implemented in this simplified Dancing Tree.")
return False
def main():
print("Dancing Tree Implementation")
t = int(input("Enter the minimum degree of the tree (t): "))
tree = DancingTree(t)
while True:
print("\nMenu:")
print("1. Insert")
print("2. Traverse")
print("3. Search")
print("4. Delete")
print("5. Exit")
choice = input("Enter your choice: ")
if choice == "1":
key = int(input("Enter the value to insert: "))
tree.insert(key)
elif choice == "2":
print("Tree traversal: ", end="")
tree.traverse()
print()
elif choice == "3":
key = int(input("Enter the value to search: "))
found = tree.search(key)
print(f"Key {key} {'found' if found else 'not found'} in the tree.")
elif choice == "4":
key = int(input("Enter the value to delete: "))
tree.delete(key)
elif choice == "5":
print("Exiting...")
break
else:
print("Invalid choice, try again.")
if __name__ == "__main__":
main()