So what I suggest is that you implement an explicit simple tree class that can be empty and that your client can hold a reference to. If you make it look a bit like a node, it can just be the parent of the root node and as far as the root node is concerned it (the root node) is a normal sub-node. Something like *(caveat: not tested, and assuming the remove() function above is really a method on a node class)*:

```
class Tree:
def __init__(self):
self.leftNode = None
# need a rightNode to look like a node, but otherwise unused.
self.rightNode = None
# This will probably be useful.
@property
def isEmpty(self):
return self.leftNode is None
def addNode(self, node):
if self.leftNode is not None:
self.leftNode = node
return
self.leftNode.add(node, parent = self)
def removeNode(self, node):
# the node will remove itself from us, the parent,
if needed
self.leftNode.remove(node, parent = self)
```

Then the client does things like:

tree = Tree() tree.isEmpty tree.addNode(node) tree.removeNode(node)

Before looking at Python, consider the following C/C++ code:

```
struct A {
virtual void suicide() {
delete this;
}
};
int main() {
A * a = new A();
a - > suicide();
return 0;
}
```

Consider a "literal translation" of the C/C++ code above into Python:

```
class A(object):
def suicide(self):
del self
a = A()
a.suicide()
```

It is also totally valid Python code, however `del self`

here does nothing (except for prohibiting you to refer to `self`

later along in the same method, because you deleted the variable from the scope).
As long as there exists a variable `a`

pointing to the created object from somewhere, its memory will not be released. Just as the memory would not be released here, for example:

a = A() b = a del a

Last Updated : 18 Jul, 2022

Why 1.c doesn’t find max in left subtree and recur for max like 1.b?

Doing this violates the property that all equal values are in right subtree. For example, if we delete (!0, 10) in below subtree and replace if with

```
Wrong Way(Equal key in left subtree after deletion)
(5, 6)(4, 10) /
Delete(5, 6) /
(4, 10) -- -- -- -- -- -- > (4, 20)\
(4, 20)
Right way(Equal key in right subtree after deletion)
(5, 6)(4, 10) /
Delete(5, 6)\
(4, 10) -- -- -- -- -- -- > (4, 20)\
(4, 20)
```

**Output: **

Root after deletion of (30, 40) 35, 45

Inserting a new node into the kd tree is similar to BST insertion. The kd tree search procedure is followed until a NULL pointer is found, indicating the proper place to insert the new node.,Searching a kd tree for the record with a specified xy-coordinate is like searching a BST, except that each level of the kd tree is associated with a particular discriminator.,Inserting a record at location (10, 50) in the kd tree of Figure 15.4.1 first requires a search to the node containing record \(B\). At this point, the new record is inserted into \(B\)’s left subtree.,In findmin, on levels using the minimum value’s discriminator, branching is to the left. On other levels, both children’s subtrees must be visited. Helper function min takes two nodes and a discriminator as input, and returns the node with the smaller value in that discriminator.

```
private E findhelp(KDNode<E> rt, int[] key, int level) {
if (rt == null) return null;
E it = rt.element();
int[] itkey = rt.key();
if ((itkey[0] == key[0]) && (itkey[1] == key[1]))
return rt.element();
if (itkey[level] > key[level])
return findhelp(rt.left(), key, (level+1)%D);
else
return findhelp(rt.right(), key, (level+1)%D);
}
```

```
private KDNode<E>
findmin(KDNode<E> rt, int descrim, int level) {
KDNode<E> temp1, temp2;
int[] key1 = null;
int[] key2 = null;
if (rt == null) return null;
temp1 = findmin(rt.left(), descrim, (level+1)%D);
if (temp1 != null) key1 = temp1.key();
if (descrim != level) {
temp2 = findmin(rt.right(), descrim, (level+1)%D);
if (temp2 != null) key2 = temp2.key();
if ((temp1 == null) || ((temp2 != null) &&
(key1[descrim] > key2[descrim])))
temp1 = temp2;
key1 = key2;
} // Now, temp1 has the smaller value
int[] rtkey = rt.key();
if ((temp1 == null) || (key1[descrim] > rtkey[descrim]))
return rt;
else
return temp1;
}
```

```
private void rshelp(KDNode<E> rt, int[] point,
int radius, int lev) {
if (rt == null) return;
int[] rtkey = rt.key();
if (InCircle(point, radius, rtkey))
System.out.println(rt.element());
if (rtkey[lev] > (point[lev] - radius))
rshelp(rt.left(), point, radius, (lev+1)%D);
if (rtkey[lev] < (point[lev] + radius))
rshelp(rt.right(), point, radius, (lev+1)%D);
}
```

This method leads to a balanced k-d tree, in which each leaf node is approximately the same distance from the root. However, balanced trees are not necessarily optimal for all applications. ,Since there are many possible ways to choose axis-aligned splitting planes, there are many different ways to construct k-d trees. The canonical method of k-d tree construction has the following constraints:[2] ,Querying an axis-parallel range in a balanced k-d tree takes O(n1−1/k +m) time, where m is the number of the reported points, and k the dimension of the k-d tree.,The nearest neighbour search (NN) algorithm aims to find the point in the tree that is nearest to a given input point. This search can be done efficiently by using the tree properties to quickly eliminate large portions of the search space.

```
from collections
import namedtuple
from operator
import itemgetter
from pprint
import pformat
class Node(namedtuple("Node", "location left_child right_child")):
def __repr__(self):
return pformat(tuple(self))
def kdtree(point_list, depth: int = 0):
if not point_list:
return None
k = len(point_list[0]) # assumes all points have the same dimension
# Select axis based on depth so that axis cycles through all valid values
axis = depth % k
# Sort point list by axis and choose median as pivot element
point_list.sort(key = itemgetter(axis))
median = len(point_list) // 2
# Create node and construct subtrees
return Node(
location = point_list[median],
left_child = kdtree(point_list[: median], depth + 1),
right_child = kdtree(point_list[median + 1: ], depth + 1),
)
def main():
""
"Example usage"
""
point_list = [(7, 2), (5, 4), (9, 6), (4, 7), (8, 1), (2, 3)]
tree = kdtree(point_list)
print(tree)
if __name__ == "__main__":
main()
```

```
((7, 2),
((5, 4), ((2, 3), None, None), ((4, 7), None, None)),
((9, 6), ((8, 1), None, None), None))
```