Insert sorted array into binary search tree - algorithm

I want to implement an algorithm that inserts sorted arrays into binary search trees but I don't want ending up with a tree that only grows to one side.
Do you have any ideas?
Thanks.

This should give you a balanced tree (in O(n)):
Construct a node for the middle element in the array and return it
(this will be the root in the base case).
Repeat from 1. on the left half of the array, assigning the return value to the left child of the root.
Repeat from 1. on the right half of the array, assigning the return value to the right child of the root.
Java-like code:
TreeNode sortedArrayToBST(int arr[], int start, int end) {
if (start > end) return null;
// same as (start+end)/2, avoids overflow.
int mid = start + (end - start) / 2;
TreeNode node = new TreeNode(arr[mid]);
node.left = sortedArrayToBST(arr, start, mid-1);
node.right = sortedArrayToBST(arr, mid+1, end);
return node;
}
TreeNode sortedArrayToBST(int arr[]) {
return sortedArrayToBST(arr, 0, arr.length-1);
}
Code derived from here.

public class SortedArrayToBST {
public TreeNode sortedArrayToBST(int[] num) {
if (num == null) {
return null;
}
return buildBST(num, 0, num.length - 1);
}
private TreeNode buildBST(int[] num, int start, int end) {
if (start > end) {
return null;
}
int mid = start + (end - start) / 2;
TreeNode root = new TreeNode(num[mid]);
TreeNode left = buildBST(num, start, mid - 1);
TreeNode right = buildBST(num, mid + 1, end);
root.left = left;
root.right = right;
return root;
}
}

Insert them in pseudo-random order, like here:
#include <stdio.h>
int array[] = {1,2,3,4,5,6,7,8,9,10};
#define COUNT 10
#define STEP 7 /* must be relatively prime wrt COUNT */
#define START 5 /* not important */
int main(void)
{
unsigned idx;
idx=START;
while(1) {
printf("[%u] = %u\n", idx, array[idx] );
// do_insert(array[idx] );
idx = (idx + STEP ) % COUNT;
if (idx == START) break;
}
return 0;
}

Related

segment tree correct but query output is not

I tried to implement segment tree algorithm for finding range minimum query in Java. Here is my complete java code. It builds the segment tree from an array. and then prints the minimum element in every range. the problem is, tree is correct (as far as I know), but the output is always the least element of whole array. :-| kindly point out where I am going wrong.
public class Solution {
static int arr[] = {-1, 2, 4, 0};
static int st[];
public static void main(String[] args) {
st = new int [ 2 * arr.length-1];
buildTree(0, 0, arr.length-1);
System.out.print("original array: ");
showArray(arr);
System.out.print("segment tree: ");
// shows segment tree
showArray(st);
System.out.println("\nqueries: \n");
// prints minimum in every range
for(int i=0; i<arr.length; i++) {
for(int j=i+1; j<arr.length; j++)
System.out.println(i+":"+j+" -> "+search(i, j));
}
}
// builds segment tree
static void buildTree(int pos, int left, int right) {
if(left == right) {
st[pos] = arr[left];
return;
}
int mid = (left + right) / 2;
buildTree(left(pos), left, mid);
buildTree(right(pos), mid+1, right);
int p1 = left(pos);
int p2 = right(pos);
st[pos] = (st[p1] > st[p2]) ? st[p2] : st[p1];
}
// left child
static int left(int pos) {
return pos * 2 + 1;
}
// right child
static int right(int pos) {
return pos * 2 + 2;
}
static int search(int left, int right) {
return rmq(0, 0, st.length, left, right);
}
// range minimum query function
static int rmq(int pos, int left, int right, int qleft, int qright) {
if((qleft > right) && (qright < left))
return Integer.MAX_VALUE;
if((qleft <= left) || (qright >= right))
return st[pos];
int mid = (left + right) / 2;
int l = rmq(left(pos), left, mid, qleft, qright);
int r = rmq(right(pos), mid + 1, right, qleft, qright);
return (l > r) ? r : l;
}
// show segment tree
static void showArray(int arr[]) {
for(Integer x : arr)
System.out.print(x+" ");
System.out.println();
}
}
You have to make following changes in your code.
First of all size of array used for storing data in segmentree datastructure should be 4 times of size of given array. Here is why?
st = new int [ 4 * arr.length - 1];
Next in search function, you third parameter for rmq must be arr.length - 1.
static int search(int left, int right) {
return rmq(0, 0, arr.length - 1, left, right);
}
And finally, you have to correct base cases and arguments in child calls in rmq function as follows:
static int rmq(int pos, int left, int right, int qleft, int qright) {
if((qleft > right) || (qright < left))
return Integer.MAX_VALUE;
if((qleft <= left) && (qright >= right))
return st[pos];
int mid = (left + right) / 2;
int l = rmq(left(pos), left, mid, qleft, Math.min(qright, mid) );
int r = rmq(right(pos), mid + 1, right, Math.max(mid + 1, qleft), qright);
return (l > r) ? r : l;
}
Hope this helps.

maximum sum of value from root to leaf in a binary tree using stack

I am trying to find the maximum sum of value from root to leaf nodes in a binary tree using stack.
I wrote the following code but there is a bug in it .
<>
Stacks s;
s.push(root);
maxSum=currSum=0;
while(!s.isEmpty()) {
temp = s.top();
s.pop();
if( temp->left == null && temp->right == null ) {
currSum = currSum+temp->data;
if(currSum > maxSum) {
maxSum = currSum;
}
currSum =0;
} else {
currSum = currSum + temp->data;
if(temp->left) s.push(temp->left);
if(temp->right) s.push(temp->right);
}
}
What I am trying to do is calculate the sum till the leaf node and assign it to maxSum.
Ex:- Binary tree is
1
/ \
2 3
/ \
4 5
1)I first push 1 and pop . currSum =1;
2) Push 3 and 2 and pop 2. cursum = 3 and push 5 and 4;
3) Stack now looks like 4<-5-<3-<1 (4 is top element)
4)Now as 4 is leaf node , I enter the if loop and add currSum = 3+4=7 and pop 4 .
5)Now temp is 5 and I set currSum=0, so currSum when I pop 5 becomes 5 .
Can anyone help me fix this bug please
10
/ \
8 2
Consider this example for your code.
First root(10) is pushed into the stack and immediately we are popping it.
Now the currsum becomes 10 and left (8) and right (2) nodes are pushed into the stack.
Now topmost element(2) is popped and added to currsum.Now currsum becomes 12.
As we reached leaf node, maxsum contains currsum value.
And currsum is made 0.
This is a mistake as we are losing the root value.
Now we pop the last element (8) and the currsum has value 8.As we reached leaf node,we compare with maxsum(12) and the final answer is
12 which is wrong.
The Code below will help you through. Try using stack in place of vector.
using namespace std;
struct node {
int data;
struct node* left;
struct node* right;
};
struct node* createNode(int k) {
struct node* temp = new node;
temp->left = NULL;
temp->right = NULL;
temp->data = k;
return temp;
}
int tsum(vector<struct node *> path) {
int sum;
int n = path.size();
int i;
for (i = 0; i < n; i++)
sum = sum + path[i]->data;
return sum;
}
int maxsum(struct node *root) {
int currsum = 0, maxsum = 0;
vector<struct node *> v;
v.push_back(root); //Push root
vector<int> visited(100, 0);
while (v.size() > 0) {
visited[v.back()->data] = 1; //whenever node is reached mark visited
if (v.back()->left != NULL && !visited[v.back()->left->data])
v.push_back(v.back()->left);
else if (v.back()->right != NULL && !visited[v.back()->right->data])
v.push_back(v.back()->right);
else {
if (!v.back()->left && !v.back()->right) {
currsum = tsum(v);
if (currsum > maxsum)
maxsum = currsum;
}
v.pop_back(); //pop here is used for backtracking
}
}
return maxsum;
}
int main() {
int sum = 0;
std::vector<int> arr;
/* Constructed binary node is
1
/ \
2 3
/ \
4 5
*/
struct node *root = createNode(1);
root->left = createNode(2);
root->right = createNode(3);
root->left->left = createNode(4);
root->left->right = createNode(5);
int s = 0;
s = maxsum(root);
cout << "SUM" << s << "\n";
return 0;
}

Dynamic prefix sum

Is there any data structure which is able to return the prefix sum [1] of array, update an element, and insert/remove elements to the array, all in O(log n)?
[1] "prefix sum" is the sum of all elements from the first one up to given index
For example, given the array of non-negative integers 8 1 10 7 the prefix sum for first three elements is 19 (8 + 1 + 10). Updating the first element to 7, inserting 3 as the second element and removing the third one gives 7 3 10 7. Again, the prefix sum of first three elements would be 20.
For prefix sum and update, there is Fenwick tree. But I don't know how to handle the addition/removal in O(log n) with it.
On the other hand, there are several binary search trees such as Red-black tree, all of which handle the update/insert/remove in logarithmic time. But I don't know how to maintain the given ordering and do the prefix sum in O(log n).
A treap with implicit keys can perform all this operations in O(log n) time per query. The idea of implicit keys is pretty simple: we do not store any keys in nodes. Instead, we maintain subtrees' sizes for all nodes and find an appropriate position when we add or remove an element using this information.
Here is my implementation:
#include <iostream>
#include <memory>
struct Node {
int priority;
int val;
long long sum;
int size;
std::shared_ptr<Node> left;
std::shared_ptr<Node> right;
Node(long val):
priority(rand()), val(val), sum(val), size(1), left(), right() {}
};
// Returns the size of a node owned by t if it is not empty and 0 otherwise.
int getSize(std::shared_ptr<Node> t) {
if (!t)
return 0;
return t->size;
}
// Returns the sum of a node owned by t if it is not empty and 0 otherwise.
long long getSum(std::shared_ptr<Node> t) {
if (!t)
return 0;
return t->sum;
}
// Updates a node owned by t if it is not empty.
void update(std::shared_ptr<Node> t) {
if (t) {
t->size = 1 + getSize(t->left) + getSize(t->right);
t->sum = t->val + getSum(t->left) + getSum(t->right);
}
}
// Merges the nodes owned by L and R and returns the result.
std::shared_ptr<Node> merge(std::shared_ptr<Node> L,
std::shared_ptr<Node> R) {
if (!L || !R)
return L ? L : R;
if (L->priority > R->priority) {
L->right = merge(L->right, R);
update(L);
return L;
} else {
R->left = merge(L, R->left);
update(R);
return R;
}
}
// Splits a subtree rooted in t by pos.
std::pair<std::shared_ptr<Node>, std::shared_ptr<Node>> split(
std::shared_ptr<Node> t,
int pos, int add) {
if (!t)
return make_pair(std::shared_ptr<Node>(), std::shared_ptr<Node>());
int cur = getSize(t->left) + add;
std::pair<std::shared_ptr<Node>, std::shared_ptr<Node>> res;
if (pos <= cur) {
auto ret = split(t->left, pos, add);
t->left = ret.second;
res = make_pair(ret.first, t);
} else {
auto ret = split(t->right, pos, cur + 1);
t->right = ret.first;
res = make_pair(t, ret.second);
}
update(t);
return res;
}
// Returns a prefix sum of [0 ... pos]
long long getPrefixSum(std::shared_ptr<Node>& root, int pos) {
auto parts = split(root, pos + 1, 0);
long long res = getSum(parts.first);
root = merge(parts.first, parts.second);
return res;
}
// Adds a new element at a position pos with a value newValue.
// Indices are zero-based.
void addElement(std::shared_ptr<Node>& root, int pos, int newValue) {
auto parts = split(root, pos, 0);
std::shared_ptr<Node> newNode = std::make_shared<Node>(newValue);
auto temp = merge(parts.first, newNode);
root = merge(temp, parts.second);
}
// Removes an element at the given position pos.
// Indices are zero-based.
void removeElement(std::shared_ptr<Node>& root, int pos) {
auto parts1 = split(root, pos, 0);
auto parts2 = split(parts1.second, 1, 0);
root = merge(parts1.first, parts2.second);
}
int main() {
std::shared_ptr<Node> root;
int n;
std::cin >> n;
for (int i = 0; i < n; i++) {
std::string s;
std::cin >> s;
if (s == "add") {
int pos, val;
std::cin >> pos >> val;
addElement(root, pos, val);
} else if (s == "remove") {
int pos;
std::cin >> pos;
removeElement(root, pos);
} else {
int pos;
std::cin >> pos;
std::cout << getPrefixSum(root, pos) << std::endl;
}
}
return 0;
}
An idea: to modify an AVL tree. Additions and deletions are done by index. Every node keeps the count and the sum of each subtree to allow all operations in O(log n).
Proof-of-concept with add_node and update_node and prefix_sum implemented:
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
self.left_height = 0
self.right_height = 0
self.left_count = 1
self.left_sum = value
self.right_count = 0
self.right_sum = 0
def set_value(self, value):
self.value = value
self.left_sum = self.left.left_sum + self.left.right_sum+self.value if self.left else self.value
def set_left(self, node):
self.left = node
self.left_height = max(node.left_height, node.right_height)+1 if node else 0
self.left_count = node.left_count + node.right_count+1 if node else 1
self.left_sum = node.left_sum + node.right_sum+self.value if node else self.value
def set_right(self, node):
self.right = node
self.right_height = max(node.left_height, node.right_height)+1 if node else 0
self.right_count = node.left_count + node.right_count if node else 0
self.right_sum = node.left_sum + node.right_sum if node else 0
def rotate_left(self):
b = self.right
self.set_right(b.left)
b.set_left(self)
return b
def rotate_right(self):
a = self.left
self.set_left(a.right)
a.set_right(self)
return a
def factor(self):
return self.right_height - self.left_height
def add_node(root, index, node):
if root is None: return node
if index < root.left_count:
root.set_left(add_node(root.left, index, node))
if root.factor() < -1:
if root.left.factor() > 0:
root.set_left(root.left.rotate_left())
return root.rotate_right()
else:
root.set_right(add_node(root.right, index-root.left_count, node))
if root.factor() > 1:
if root.right.factor() < 0:
root.set_right(root.right.rotate_right())
return root.rotate_left()
return root
def update_node(root, index, value):
if root is None: return root
if index+1 < root.left_count:
root.set_left(update_node(root.left, index, value))
elif index+1 > root.left_count:
root.set_right(update_node(root.right, index - root.left_count, value))
else:
root.set_value(value)
return root
def prefix_sum(root, index):
if root is None: return 0
if index+1 < root.left_count:
return prefix_sum(root.left, index)
else:
return root.left_sum + prefix_sum(root.right, index-root.left_count)
import random
tree = None
tree = add_node(tree, 0, Node(10))
tree = add_node(tree, 1, Node(40))
tree = add_node(tree, 1, Node(20))
tree = add_node(tree, 2, Node(70))
tree = update_node(tree, 2, 30)
print prefix_sum(tree, 0)
print prefix_sum(tree, 1)
print prefix_sum(tree, 2)
print prefix_sum(tree, 3)
print prefix_sum(tree, 4)

find kth smallest in bst using recursive inorder

I am trying to find the kth smallest in BST.
public void findKthSmallest(BSTNode<T> node, int k) {
if(node == null)
return;
findKthSmallest(node.left, k);
count++;
if (k == count) {
System.out.println("Kth smallest: " + node.data);
return;
}
findKthSmallest(node.right, k);
}
here count is a instance variable. I am not able to figure out how to implement it using count as a parameter(local varaible) in the function, since it get resets when function returns.
Any idea??
Since this is Java and you have no pass by reference, I think the easiest is to modify findKthSmallest to return how many nodes are in the subtree rooted at node. Something like this:
public int findKthSmallest(BSTNode<T> node, int k) {
if(node == null)
return 0;
int left = findKthSmallest(node.left, k);
if (k == left + 1) {
System.out.println("Kth smallest: " + node.data);
return 1;
}
return 1 + left + findKthSmallest(node.right, k);
}
I would like to make a small correction in IVlad's approach. When we are searching left, the problem is to find kth smallest. However, when searching right we need to find k-left-1 (discarding the left subtree+current node). In java we cant return multiple values other than creating a class. So made a hack for that by passing an array as parameter. Here is the code:
public int kthSmallest(TreeNode node, int k, TreeNode kthNode[]) {
int leftCount = 0;
int rightCount = 0;
if(node.left!=null) {
leftCount = kthSmallest(node.left, k, kthNode);
}
if(leftCount==k-1) {
kthNode[0] = node; // We can also return from here
}
if(node.right!=null) {
rightCount = kthSmallest(node.right, k-leftCount-1, kthNode);
}
return leftCount + 1 + rightCount;
}
public TreeNode kthSmallest(TreeNode node, int k) {
TreeNode kNode[] = new TreeNode[1];
int nodeCount = kthSmallest(node, k, kNode);
return kNode[0];
}

Nth largest element in a binary search tree

How to find the Nth largest node in a BST?
Do I keep a count variable while doing In Order Traversal of a BST? Return the element when the count = N???
The idea is very simple: traverse the tree in decreasing order of the values of each node. When you reach the Nth node, print that node value. Here is the recursive code.
void printNthNode(Node* root, int N)
{
if(root == NULL)
return;
static int index = 0; //These will initialize to zero only once as its static
//For every Node go to the right of that node first.
printNthNode(root->right, N);
//Right has returned and now current node will be greatest
if(++index == N)
{
printf("%d\n", root->data);
return;
}
//And at last go to the left
printNthNode(root->left, N);
}
Edit -
As per the comments below, looks like this is one-time call function due to the static local variable. This can be solved by passing wrapper object for index as follows:
class WrapIndex {
public: int index;
};
and method signature would change to
void printNthNode(Node* root, int N, WrapIndex wrapInd)
Now, we don't need a local static variable; instead use index of the wrapper object. The call would look like
WrapIndex wrapInd = new WrapIndex();
wrapInd.index=0;
printNthNode(root,7,wrapInd);
wrapInd.index=0;
printNthNode(root,2,wrapInd);
Hint: use inorder traversal of the tree. It can print out the items in sorted order, so you can sure find the Nth largest item. Keep a counter as you "walk", incrementing each time you "visit" a node.
Edit: while IVlad's answer is indeed faster, it requires you to keep extra information in the nodes. This answer doesn't but it's O(n). Just pointing out that this is a tradeoff you have to be aware of.
See my answer here. You can do this in O(log n) on average where n = number of nodes. Worst case is still O(n) IF the tree isn't balanced (always O(log n) if it is balanced however). In order traversal is always O(n) however.
Use a inverted inorder tranversal.that is go to right child first instead of left child.
recursively this can be obtained as follows:
The most important issue that a global count must be used when considering recursive solution.
reverseInorder(root){
if(root!=null){
reverseInorder(root->rightChild);
self
reverseInorder(root->leftChild);
}
}
Solution in java
package datastructure.binaryTree;
import datastructure.nodes.BinaryTreeNode;
public class NthElementFromEnd {
private BinaryTree tree=null;
int currCount=0;
public NthElementFromEnd(int[] dataArray) {
this.tree=new BinaryTree(dataArray);
}
private void getElementFromEnd(int n){
getElementFromEnd(this.tree.getRoot(),n);
}
private void getElementFromEnd(BinaryTreeNode node,int n){
if(node!=null){
if(currCount<n)
getElementFromEnd(node.getRightChild(),n);
currCount++;
if(currCount==n)
{
System.out.print(" "+node.getData());
return;
}
if(currCount<n)
getElementFromEnd(node.getLeftChild(),n);
}
}
public static void main(String args[]){
int data[]={1,2,3,4,5,6,7,8,9};
int n=2;
new NthElementFromEnd(data).getElementFromEnd(n);
}
}
int nLargeBST(node *root, int N) {
if (!root || N < 0) {
return -1;
}
nLargeBST(root->left, N);
--N;
if(N == 0) {
return root->val;
}
nLargeBST(root->right, N);
}
This piece of code is from my assignment and one of the condition was not to use
arrays. In order to make the code more compact and readable you can use
stringName.split("|"). Since the method is recursive I use the stringBuilder
which has the following structure: "counter|orderOfElementToFind|dataInrequiredNode"
protected StringBuilder t(StringBuilder s)
{
if (lc != null)
{
lc.t(s);
}
if((s.toString().charAt(s.toString().length() - 1)) == '|')
{
String str = s.toString();
s.delete(0, s.length());
int counter = 0, k = 0;
String strTemp = "", newStrBuilContent = "";
for (int i = 0, c = 0 ; i < str.length(); ++i)
{
if (c == 0)
{
if (str.charAt(i) != '|')
{
strTemp += str.charAt(i);
}
else
{
counter = Integer.parseInt(strTemp);
++c;
strTemp = "";
}
}
else
{
if (str.charAt(i) != '|')
{
strTemp += str.charAt(i);
}
else
{
k = Integer.parseInt(strTemp);
}
}
counter ++;
newStrBuilContent = (counter + "|" + k + "|");
s.append(newStrBuilContent);
if (counter == k)
{
double ldata = this.getData();
s.append(ldata);
}
}
if (rc != null)
{
rc.t(s);
}
return s;
}
and the method call:
// the value of counter ad the beginning is 0 and data
// segment is missing
String s = ("0|" + order +"|");
StringBuilder strBldr = new StringBuilder(s);
String content = sTree.t(strBldr).toString();
s = "";
for (int i = 0, c = 0; i < content.length(); ++i)
{
if (c < 2)
{
if (content.charAt(i) == '|')
{
++c;
}
}
else
{
s += content.charAt(i);
}
}
`
Maintain size of subtree at eachnode(root.size some thing like that). for example {2,3,1} is a binary tree with root 2 then the size of node (2) is 3, node (1) size is 1, and node (2) size is 1
if u want to find 4 th larget element in the tree with root node size 23 , think about its rank
the max element rank is 23, because the root node size is 23. so 4 th largest element rank is 23-4+1= 20
so we have to find 20th rank element in the given tree
initially declare a rank=0 flag to zero
starting from root node find its rank (rank+ size of left child + 1) for example left child size is 16 then root element rank is 17(rank+size of left child +1)
so we have to look for the element with the rank 20. so obviously we have to traverse to its right child
traverse to right child and based on above formula find right child rank(based on above formula, note: now rank flag value is is 17),decide whether to go right or left based on the rank
repeat this process recursevely untill we found rank==20
I would do it by going though the tree from biggest to smallest element and returning value when asked position is reached. I implemented similar task for second largest value. Value of 2 is hardcoded, but is it easy to change with additional parameter :)
void BTree::findSecondLargestValueUtil(Node* r, int &c, int &v)
{
if(r->right) {
this->findSecondLargestValueUtil(r->right, c, v);
}
c++;
if(c==2) {
v = r->value;
return;
}
if(r->left) {
this->findSecondLargestValueUtil(r->left, c, v);
}
}
int BTree::findSecondLargestValue()
{
int c = 0;
int v = -1;
this->findSecondLargestValueUtil(this->root, c, v);
return v;
}
// C++ program to find k'th largest element in BST
#include<iostream>
using namespace std;
struct Node
{
int key;
Node *left, *right;
};
// A utility function to create a new BST node
Node *newNode(int item)
{
Node *temp = new Node;
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
// A function to find k'th largest element in a given tree.
void kthLargestUtil(Node *root, int k, int &c)
{
// Base cases, the second condition is important to
// avoid unnecessary recursive calls
if (root == NULL || c >= k)
return;
// Follow reverse inorder traversal so that the
// largest element is visited first
kthLargestUtil(root->right, k, c);
// Increment count of visited nodes
c++;
// If c becomes k now, then this is the k'th largest
if (c == k)
{
cout << "K'th largest element is "
<< root->key << endl;
return;
}
// Recur for left subtree
kthLargestUtil(root->left, k, c);
}
// Function to find k'th largest element
void kthLargest(Node *root, int k)
{
// Initialize count of nodes visited as 0
int c = 0;
// Note that c is passed by reference
kthLargestUtil(root, k, c);
}
/* A utility function to insert a new node with given key in BST */
Node* insert(Node* node, int key)
{
/* If the tree is empty, return a new node */
if (node == NULL) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
/* return the (unchanged) node pointer */
return node;
}
// Driver Program to test above functions
int main()
{
/* Let us create following BST
50
/ \
30 70
/ \ / \
20 40 60 80 */
Node *root = NULL;
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
int c = 0;
for (int k=1; k<=7; k++)
kthLargest(root, k);
return 0;
}
Swift version. This follows closely with what Vallabh Patade said. The counter is increased by 1 when it tries to go through a node that has no child though. A bit different than his.
class BinaryNode {
var val: Int
var left: BinaryNode?
var right: BinaryNode?
init(value: Int) {
self.val = value
}
}
func findMaxValue(_ n: Int, from root: BinaryNode?) {
var counter = 0
maxValue(counter: &counter, n: n, node: root)
}
private func maxValue(counter: inout Int, n: Int, node: BinaryNode?) {
if node == nil {
counter += 1
return
}
maxValue(counter: &counter, n: n, node: node?.right)
// If the counter has reached the nth node we're looking for.
if counter == n {
if let val = node?.val { print(val) }
}
maxValue(counter: &counter, n: n, node: node?.left)
}
Here is how you can do this by a slight modification of the in-order traversal of the binary search tree - we are finding the kth largest element;
void kthLargest(Node node, int k, int count) {
if(node != null) {
nthLargest(node.left,k,count); //traversing the left node
//while visit the node we do the following
count++; // increment the count and check if that is equal to k
if ( count == k ) {
System.out.println("Node found "+node.value);
}
nthLargest(node.right,k,count); //traversing the right node
}
}
But the problem in this way you are going to reach the kth smallest element and hence you method call should be this: as kth largest element = (n-k)th smallest element.
nthLargest(root,n-k,0);
K’th Largest Element in BST . Learn how to think for such problem and solve with recursion . Kth Larget Explanation Recursion

Resources