I have a binary search tree in C, the goal currently is to find the Nth element in the tree. I am attempting to do this recursively, however this is not paramount. I have access to the amount of nodes under any given node (inclusive).
I tried this block of code:
TreeNode* findNthElement(int N, TreeNode* tree) {
static int count = 0;
printf("nodeCount: %d\nN: %d\nCount: %d\n", tree->nodeCount, N, count);//debug
//null case
if (tree == NULL) {
return NULL;
}
//recursion
if (count <= N) {
findNthElement(N, tree->left);
count++;
if (count == N) {
count = 0;
return tree;
}
findNthElement(N, tree->right);
}
}
This is supposed to be a recursive function to complete my task but count's value is always 0 even though it is static. I have also tried initializing count outside of the function and resetting it to 0 upon success or failure but that has also not succeeded.
Your code ignores the node that is returned from the recursive call, so if that recursive call had found the target node, the caller is not aware of it. Moreover, after the findNthElement(N, tree->right) call, nothing is returned.
Also, you shouldn't use a static count. The counting logic can be satisfied by reducing the value that will be passed as N-argument to the recursive call.
Here is an implementation:
TreeNode* findNthElement(int n, TreeNode* tree) {
if (tree == NULL) {
return NULL;
}
int currentNum = tree->left == NULL ? 1 : tree->left->nodeCount + 1;
return n == currentNum ? tree // Found it!
: n < currentNum ? findNthElement(n, tree->left)
: findNthElement(n - currentNum, tree->right);
}
this code is beyond my knowledge, but maybe count++ needs to go before recursing? Because you are calling the recursion without increasing the count in your code.
Example:
if (count <= N) {
count++;
findNthElement(N, tree->left);
You dont have to define count as static at all, you can directly increment parameter and call recursively until N == count.
Whenever you call the function, even recursively, then a new count variable will be created in the memory stack.
TreeNode* findNthElement(int N, TreeNode* tree, int count) {
TreeNode * nthTree = NULL;
if(tree == NULL)
return NULL;
//Found the Nth element
if (count == N){
return tree;
}
//Not using ++count just for clarity
//First it will check left subtree, if its Nth then return it else go right
nthTree = findNthElement(N, tree->left, count+1); //Recursive call for left node
//Recursive call for right node
return (nthTree == NULL) ? findNthElement(N, tree->right, count+1) : nthTree;
}
in order to find the nth smallest element in BST, you can apply logic as follows:
using System.Collections.Generic;
public int smallElement(int k)
{
Node<T> node = Root;
int count = k;
int sizeOfSubTree =0;
while (node != null)
{
sizeOfSubTree = node.SizeOfLeftSubTree();
if(sizeOfSubTree +1 == count)
{
return node.Value;
}
else if(sizeOfSubTree +1 < count)
{
node=node.Right;
count -= sizeOfSubTree +1 ;
}
else
{
node = node.Right;
}
}
return -1;
}
you can also check following resources to get help:
in-order traversal to find nth node
Find k’th smallest node in a Binary Search Tree (BST)
hope this might help you.
Related
I am trying to implement a function in C that will find the smallest int that is greater than or equal to a given int in an AVL. For example:
if I have an AVL tree consisting of 1,2,3,4,5,6,7 and I put in 6, it should return 6.
if I have an AVL tree consisting of 1,2,3,4,6,7 and I put in 5, it should return 6.
if none are found, return -1.
I have found a case (there could be more) where this implementation fails. If I have an AVL tree of 1,2,3,4,5,6,7 and I input 3 it incorrectly returns 4. This case occurs when the ROOT is bigger than the input. I am not sure how to fix this though. There could also be other cases — if you could let me know that would be great.
Here is my attempt:
int findLeastGreatest(Node *root, int input) {
// Never found
if (root->left == NULL && root->right == NULL && root->data < input)
return -1;
// Found
if ((root->data >= input && root->left == NULL) ||
(root->data >= input && root->left->data < input))
return root->data;
if (root->data <= input)
return findLeastGreatest(root->right, input);
else
return findLeastGreatest(root->left, input);
}
Your function has problems: you are testing too many conditions together:
Here is a simpler approach:
if the root is NULL, you should return -1;
if the root->data < input, you should just recurse on the root->right node
if root->data == input you should just return input.
otherwise, you should recurse on the left node and return the result if found, otherwise return root->data.
Here is an implementation:
int findLeastGreatest(const Node *root, int input) {
if (!root)
return -1;
if (root->data < input)
return findLeastGreatest(root->right, input);
if (root->data == input)
return input;
int value = findLeastGreatest(root->left, input);
if (value == -1)
return root->data;
else
return value;
}
If you are not required to produce a recursive version, here is a simpler version with a while loop:
int findLeastGreatest(const Node *root, int input) {
int value = -1;
while (root) {
if (root->data < input) {
root = root->right;
} else {
value = root->data;
root = root->left;
}
}
return value;
}
I find it easier to write this function in a loop. The algorithm in the pseudocode below should work. The key idea is to not assign to bound unless the condition (node.key >= key) is true, in which case you must also traverse left to look for potentially smaller keys that satisfy the same condition. Otherwise, traverse right to look for larger keys that might satisfy.
least_greatest(node, key):
bound = -1
while node != NULL:
if node.key >= key:
bound = node.key # found a bound, but it might not be the least bound
node = node.left # look for a smaller key
else:
node = node.right # look for larger keys
return bound
P.S. this function is called upper_bound in the C++ STL, and I've also seen this called "least upper bound".
I am trying to find the depth of a specific node noted by a pointer in c, but I cant seem to get it right
int depth(Node *root, Node *N){
// Need to find the root N
// At the same time count how many depths you can go down
// If the root is NULL, then no tree and return -1
if (root == NULL){
return -1;
}
// If the root node equals the node N, then return 0
if (root->data == N->data){
return 0;
}
// Search the tree and add one each time recursion called
int count = -1;
if (N->data < root->data){
root->left->data = depth(root->left, N);
count++;
}
else if (N->data > root->data){
root->right->data = depth(root->right, N);
count++;
}
else{
}
return count;
}
Any help in solving this would be appreciated.
The pseudo code for such a function is along the lines of this, assuming root = level 0:
int search (const node_t* node, int level)
{
if(node == NULL)
return -1;
if(node->data == key)
return level;
const node_t* node next;
if(node->data < key)
next = node->right;
else if(node->data > key)
next = node->left
return search (next, level+1);
}
First called as search(root, 0);
Though as usual, recursion in C is almost certainly the wrong solution to any problem. The above can rather trivially be rewritten as sane, readable, fast loops instead.
The successor of an element in a BST is the element's successor in the
sorted order determined by the inorder traversal. Finding the
successor when each node has a pointer to its parent node is presented
in CLRS's algorithm textbook (Introduction to Algorithms by MIT
press).
Is there a way to find the first value that is bigger than X without parent in the struct? Like:
typedef struct tree tree;
struct tree{
int value;
tree *left;
tree *right;
};
//Function:
tree *find_first_bigger(tree *t, int x){}
I tried working with:
tree *find_first_bigger(tree *t, int x){
if(t == NULL)
return NULL;
if((*t)->value > x)
find_first_bigger((*t)->left, x);
else if((*t)->value < x)
find_first_bigger((*t)->right), x);
else if((*t)->value == x){
if((*t)->right != NULL)
return tree_first_bigger((*t)->right);
else
return tree;
}
}
With this example(it's using letter but there its not a problem), if I try to search the first bigger than N(It should return me O) but it returns me N.
You have done 90% of the job.Allow me to do the remaining 10%.
Since t is a pointer to structure you should use t->left instead of (*t)->left and same applies while accessing right and value fields of the struct.
Now, Just modify your function as:
Add this as first line of your function
static tree* PTR=NULL;
Modify the second if condition as:
if(t->value > x)
{
PTR=t;
find_first_bigger(t->left, x);
}
Modify the second else if condition as:
else if(t->value == x)
{
if(t->right != NULL)
{
t=t->right;
while(t->left!=NULL)
t=t->left;
return t;
}
else return PTR;
}
Hence the correct function is
tree *find_first_bigger(tree *t, int x)
{
static tree* PTR=NULL;
if(t == NULL)
return NULL;
if(t->value > x)
{
PTR=t;
find_first_bigger(t->left, x);
}
else if(t->value < x)
find_first_bigger(t->right, x);
else if(t->value == x)
{
if(t->right != NULL)
{
t=t->right;
while(t->left!=NULL)
t=t->left;
return t;
}
else return PTR;
}
}
In the main function if pointer returned is NULL, this means that :the key itself is the largest key. Feel free for any queries.
I haven't tested this, but I think it should work. Let me know if it is wrong.
//c++ 11
#include<iostream>
using namespace std;
struct BSTNode{
int val;
BSTNode* left;
BSTNode* right;
};
int FindJustLarger(BSTNode*& node, int token, int sofarlarge){
// for invalid inputs it will return intial value of sofarlarge
// By invalid input I mean token > largest value in BST
if(node == nullptr)
return sofarlarge;
else if(node->val > token){
sofarlarge = node->val;
return FindJustLarger(node->left, token, sofarlarge);}
else
return FindJustLarger(node->right, token, sofarlarge);}
int main(){
BSTNode* head = new BSTNode{5, nullptr, nullptr};
FindJustLarger(head, 5, NULL);
delete head;
return 0;}
Some changes you can do in your code:
You have to return the values from the recursive calls
If the value is not found, return NULL. This means returning NULL if t->right == NULL on the last if.
When going to the left, if the value is not found there, the answer must be the node itself. In the case of N, it is the last node where we turn left: O. If it were P, the answer would be T itself.
After all those changes, the code should look like this:
tree *find_first_bigger(tree *t, int x){
if(t == NULL)
return NULL;
if(t->value > x) {
tree *answer = find_first_bigger(t->left, x);
if (answer != NULL)
return answer;
return t;
} else if(t->value < x) {
return find_first_bigger(t->right, x);
} else if(t->value == x) {
if (t->right != NULL)
return tree_first_bigger(t->right);
return NULL;
}
}
You can find the entire code I used to test in this gist.
In your question, you seemed to indicate that you want to find out InOrderSuccessor() of the the given value 'x'.
If 'x' does not necessarily exist in the tree, we need to change the algorithm. Given the example you provided and the problem statement, here is code for finding the next element in a BST.
The key cases are :
No greater element exists, because 'x' is the biggest.
'x' has a right child ?
YES: get left-most child of x's right sub-tree.
NO : return parent.
Key observation is that we don't update the parent pointer, whenever we go right in the tree.
tree *ptr = root;
tree *prnt = NULL;
while (ptr != NULL) {
if (x == ptr->key) {
if (ptr->right != NULL) {
return GetLeftMostChild(ptr->right);
} else {
return prnt;
}
} else if (x > ptr->key) {
ptr = ptr->right;
} else {
prnt = ptr;
ptr = ptr->left;
}
}
Here is the definition for leftMostChild()
tree *GetLeftMostChild(tree *n) {
tree *ptr = n;
while (ptr->left != NULL) {
ptr = ptr->left;
}
return ptr;
}
Hello stackoverflowers,
i am facing a problem with my function in C, i want to create a function that give me the min and max value in BST.
The problem is when i use this function it returns the same value for min and max:
void Find_Min_Max(node *bt,int* maxint,int* minint)
{
node *tmp = bt;
if( bt == NULL)
{
*maxint = 0; // Only if the tree contains nothing at all
*minint = 0; // Only if the tree contains nothing at all
}
if( bt->left)
return Find_Min_Max(bt->left,&(*maxint),&(*minint));
*minint = bt->data;
if( tmp->right)
return Find_Min_Max(tmp->right,&(*maxint),&(*minint));
*maxint = tmp->data;
}
But when i use it to give me just one result max/min, i delete this part of code, everything work perfectly:
if( tmp->right)
return Find_Min_Max(tmp->right,&(*maxint),&(*minint));
*maxint = tmp->data;
Any idea how this will work?.
Thank you in advance.
It's not really easy / intuitive to recursively compute max and min at the same time in the same function. I would even say it's not possible, because those are two completely different traversals.
You should have a function to get the minimum, a function to get the maximum, and call each of them inside Find_Min_Max.
This would be a possible approach:
int find_min(node *n) {
if (n == NULL) {
return 0;
}
while (n->left != NULL) {
n = n->left;
}
return n->data;
}
find_max is similar, but traverses right links only:
int find_max(node *n) {
if (n == NULL) {
return 0;
}
while (n->right != NULL) {
n = n->right;
}
return n->data;
}
Then, find_min_max() is easy to code:
void find_min_max(node *bt, int *min, int *right) {
*min = find_min(bt);
*max = find_max(bt);
}
find_min() and find_max() could be recursive, but the iterative approach has the desirable property of using constant memory (and consequently avoids stack overflows).
To find the minimum value in a BST, you follow the chain of left children from the root until you reach a node with no left child. That node contains the minimum value (even if it does have a right child).
The algorithm to find the maximum is exactly the mirror image: follow the chain of right children until you reach a node with no right child. That node contains the maximum value.
It does not make sense to try to perform both traversals at the same time, because they follow completely different paths. If you want a single function to discover both the minimum and the maximum value, then it doesn't make much sense for that function itself to be recursive. It could, however, wrap calls to two separate recursive functions, one to find the minimum, and the other to find the maximum.
Finding min and max value in a BST are very easy. Please check both code snippet below I explain how these codes work.
public int minValueInBST(Node node){
if (node == null) throw new IllegalStateException();
Node current = node;
while (current.leftChild != null) {
current = node.leftChild;
}
return current.value;
}
To find the minimum value in BST we have to find the leftmost leaf node because that node contains the minimum value. So at first, we check the root node is null or not if null we throw IllegalStateException otherwise we find the left node, at last, we return the left node value.
public int maxValueInBST(Node node){
if (node == null) throw new IllegalStateException();
Node current = node;
while (current.rightChild != null) {
current = node.rightChild;
}
return current.value;
}
To find the maximum value in BST we have to find the rightmost leaf node because that node contains the maximum value. So at first, we check the root node is null or not if null we throw IllegalStateException otherwise we find the right node, at last, we return the right node value.
// try this
tree_node *min(tree_node *root)
{
if (!root)
{
printf("Tree is empty");
exit(1);
}
tree_node *ret_val;
if (root->left == NULL)
{
ret_val = root;
}
else
{
ret_val = min(root->left);
}
return ret_val;
}
tree_node *max(tree_node *root)
{
if (!root)
{
printf("Tree is empty");
exit(1);
}
tree_node *ret_val;
if (root->right == NULL)
{
ret_val = root;
}
else
{
ret_val = max(root->right);
}
return ret_val;
}
complete code
Hello I've run into an issues I cannot seem to resolve. I have a BST that I am traversing through and checking ranks. I have a method checkRank(link head, targRank) that takes in the head node and traverses through the tree until it finds a node with an equal rank to targRank. What I am trying to do is have the checkRank function return the current node it found the equal rank at. What would be the best way to achieve this because all my attempts seem to return the current node as the head?
typedef struct node* link;
struct node
{
Item item; // Data for this node
link l, r; // left & right links
int rank;
};
Func call:
link head;
checkRank(head, 13);
Func:
link checkRank(link h,int targetRank)
{
if (h != NULL)
{
if (h->rank < targRank)
{
checkRank(h->r, targRank);
}
if (h->rank > tarRank)
{
checkRank(h->l, targtRank);
}
if (h->rank == targRank)
{
return ??;
}
}
else
{
printf("Equiv rank could not be found\n");
}
}
First of all, you need to return something along each path. Have you considered something like the following:
link check_rank(link h, int target) {
if (h == NULL) {
printf("equivalent rank could not be found\n");
return NULL;
}
if (h->rank < target)
return check_rank(h->r, target);
if (h->rank > target)
return check_rank(h->l, target);
return h;
}
Functions have to always return a value and many recursive functions will follow the pattern of (1) return a sentinel to stop recursion when the appropriate condition is met or (2) recurse and return whatever the recursive call returns.