Another approach is to enhance the BST to keep track of the sizes of subtrees. By having this information in each node, we can locate the kth smallest or largest element in O(logN) on average. The algorithm operates as follows: Check if the root node contains the Kth smallest element: if the number of elements in the left subtree of the root (denote this count as 'L') equals K-1, then the root is the Kth node. If the root's value exceeds the Kth smallest element, it indicates that the Kth node is in the left subtree. Thus, we make a recursive call to the left subtree. Conversely, if the root's value is less than the Kth smallest element, then the Kth node is found in the right subtree. In this case, we adjust k by subtracting the count of nodes in the left subtree and the current node, and then recursively call for the right subtree. Here is the Python code: class Node : def __init__ ( self , item , left = None , right = None ) : self . item = item self . left = left self . right = right self . count = 1 # Initially count is 1 def kth_smallest ( root , k ) : # Base case if root is None : return None # If count is the same as K if root . count == k : return root . item # If count is greater, search in left subtree if root . count > k : return kth_smallest ( root . left , k ) # Otherwise, search in right subtree return kth_smallest ( root . right , k - root . count ) def kth_largest ( root , k ) : # Convert k to find the kth largest in BST n = root . count # Total nodes in BST return kth_smallest ( root , n - k + 1 ) The average time complexity for both operations is O(logN), assuming the tree is balanced.