return current node from BST - c

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.

Related

How do I find the Nth element in a binary search tree?

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.

How to find the depth of a specific node in a BST in c

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.

searching an element in binary tree using in order traversal

struct tnode
{
int val;
struct tnode *left;
struct tnode *right;
};
int search(struct tnode *root, int val)
{
int p = 0;
int q = 0;
if (!root) return 0;
p = search(root->left, val);
if (p == 1) return 1;
if (root->val == val) return 1;
q = search(root->right, val);
if (q == 1) return 1;
}
I am not understanding how the above code is returning 0 when val is not found while searching the tree.
What you have there is an unstructured function. There are four return statements and five possible return paths. One of the returns explicitly returns zero, the others explicitly return 1, therefore either you are calling search with NULL for root or the fifth implicit return path just happens to return zero.
Dial up the warning level on your compiler, it should have flagged the fact that not all execution paths return a value.
I suggest you rearrange your logic such that there is a single return statement at the end of the function.
Here, I am using stack for the iterative inorder traversal of a tree.
int find_element(struct node *root,int val){
if(!root) return 0;
std::stack<node*> s;
while(!s.empty() || root){
if(root){
s.push(root);
root=root->left;
}
else
{
root=s.top();
s.pop();
if(root->val==val) return 1;
root=root->right;
}
}
return 0;
}

Find the first key bigger than X on Binary Search Tree

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;
}

Find max and min value of BST

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

Resources