I used the search function, and while I found some similar threads I did not find one that exactly covered my issue.
I am attempting to do a look up of a BST using recursion and an in-order traversal , so I want to keep track of the position of the elements.
I have the following code, but it is not doing what I want it to do. It is doing the correct traversal, but the position is not correct.
void startProces(int x)
{
void inOrder(x,*n,*Position)
}
void inOrder(int x, Node *n, int *Position)
{
int counter = *Position;
counter++;
Position = &counter;
}
This is a homework assignment, so please avoid giving me a direct solution. Also please avoid giving me a suggestion that involve having to rewrite the function parameters as I'm locked in. I would appreciate insight on why my position value is not increment properly. I know that my function currently isn't doing anything once it finds the value. I was planning on implementing that once I figured out this issue.
Clarification: I have an insert function, not shown here. If I insert the nodes (15,5,3,12,10,13,6,7,16,20,18,23) I get the in-order traversal (3,5,6,7,10,12,13,15,16,18,20,23). I want this to correspond to (1,2,3,4,5,6,7,8,9,10,11,12). Eventually when I run something like startProcess(10), I want inOrder to print 5.
Your code copies a variable on the stack and passes the address of that variable. So, for each child node, the value will always be the parent node's value plus one, instead of the previously traversed node's value plus one.
Specifically, this line copies it...
int counter = *Position;
The variable Position is a pointer, where counter is a local variable. The pointer points to the address you give it using &. Every time you call inOrder, it creates a new counter variable that's scoped to that function call.
So, this line...
Position = &counter;
sets the pointer to the counter instance in the above function call. All you need to do is pass a pointer to one specific instance instead of the copies.
Related
I am trying to write this function that will store the Balance of each node in a BST and store it inside the node. In my BST I have added variable bal to store it.
I am still a beginner when it comes to recursion so excuse any errors i just need help to see if my logic is correct or if there is a better way!
Here is my function:
void calculateBalanceValue(BinaryNode *& t)
{
if (t==nullptr) return;
int left = height(t->left);
int right = height(t->right);
t->bal=abs(left -right);
calculateBalanceValue(t->right);
calculateBalanceValue(t->left);
}
The logic looks reasonable to me, but it looks to me like it would be fairly trivial to make it roughly twice as fast.
Right now, you traverse each sub-tree once to compute its height, then you traverse at again to calculate its balance.
Since it needs to traverse the sub-trees to do its job anyway, I'd have calculateBalance return the height of the tree. That way it's fairly trivial to compute both the balance and the height with a single traversal.
Since we don't want to modify a pointer being passed to this function, I'd just pass the pointer by value.
int calculateBalanceValue(BinaryNode *t)
{
if (t==nullptr)
return 0;
int left = calculateBalance(t->left);
int right = calculateBalance(t->right);
t->bal=abs(left -right);
return 1 + std::max(left, right);
}
As an aside, if you want critiques of working code, you might want to check on Stack Exchange's Code Review web site, which is devoted to exactly that.
is there a way to implement bsearch() to find multiple instances of key.
for example: (obj*)bsearch(key=r,arr,elements,sizeof(obj),(int(*)(const void*, const void*)bcompare);
The code I currently wrote only finds the first instance and cannot proceed past the first found due to how it works.
getline(target,81);
if(strcmp(target,"exit") == 0 || strcmp(target, "") == 0) break;
p = (Info*)bsearch(target,list,num,sizeof(Info),(int(*)(const void*, const void*))bcompare);
int foundIndex = (int)(p-list);
if(!p){
err_dis1_win();
clrscr();
}
else{
display_record(p);
cout << "\n\n found at index " << foundIndex << "\n";
getch();
clrscr();
}
Variables:
p - is a pointer to object of class Info
target - arr of char
list - arr of obj
foundIndex - index of element found
Info - derived class from base class
**compare function
int bcompare(char *a,Info *b){
return(strncmpi(a, b -> get_name(), strlen(a)));
}
I cannot use other methods such as std::find or writing my own binary search function and have to use bsearch()
I have tried loops inside the else block, and the compare function using the varible foundIndex, as well as using a while loop on the return value looping through the obj list arr. Is there a way to start at a specific index. I appreciate any help. I am not looking for code but a general push in the right direction. Thank you.
Caveat - The current code compiles and runs as expected however, the functionality that I want, cannot be figured out by myself. Google and search on Stackoverflow has not produced an related issue.
Since bsearch() returns only one item, I interpret "find multiple instances of key" as "find the first instance of a key". The caller can then step forward through the array from that item to process each item matching the key, until it reaches the end or reaches an item that does not match.
If you must use the standard library's bsearch() function and persuade it to find the first item matching a given key, then all you really have to work with is the comparison function you present. bsearch() will return an item that matches the key according to that function, but if more than one item matches then there is no guarantee which one will be returned. You must ensure, then, that only the item you want matches.
You can approach that with an appropriate implementation of the comparison function, but there is a significant problem. The function will in some cases need to evaluate the item preceding the one specified to it, but it must not attempt to examine an item preceding the array's first. bsearch() does not itself convey any information about the array bounds to the comparison function.
There are at least two possible solutions, neither of them stellar.
Store the array lower bound in some well-known location that the function can access. For example, if the comparison function is a static member function, then maybe you would use a static variable of its class. But that is not thread-safe. You could do something similar with thread-local variables, but even then it's ugly. Either way, you have to be sure to set that variable appropriately before you call bsearch(), and that's ugly, too.
OR
Ensure that you never bsearch() for the first item. One way you could do that would be by checking preliminarily whether the first item matches (but not via the comparison function), and using it directly instead of calling bsearch() in the event that it does match. I'd wrap that in a method, myself, and if you must not do so then requiring that such a calling discipline be employed manually is also ugly.
Having chosen one of the above, you can implement a comparison function that looks at the previous item's key in addition to the specified item's. Something along these lines (which assumes the second alternative):
struct my_item {
int key;
void *data;
};
// bsearch() passes the target item as the first argument, and the one to compare
// to it as the second
int compare_items(const void *to_find, const void *to_check) {
const struct my_item *to_find_item = (const struct my_item *) to_find;
const struct my_item *to_check_item = (const struct my_item *) to_check;
// Check first how the key members are ordered
if (to_find_item->key < to_check_item->key) {
return -1;
} else if (to_find_item->key > to_check_item->key) {
return 1;
} else {
// The key members match, so check whether we're looking at the first
// such item.
const struct my_item *previous_item = to_check_item - 1;
// If the previous item's key does match, then we know the item we're
// looking for is an earlier one than we are presently checking.
return (previous_item->key == to_check_item->key) ? -1 : 0;
}
}
I use the following method to traverse* a binary tree of 300 000 levels:
Node* find(int v){
if(value==v)
return this;
else if(right && value<v)
return right->find(v);
else if(left && value>v)
return left->find(v);
}
However I get a segmentation fault due to stack overflow.
Any ideas on how to traverse the deep tree without the overhead of recursive function calls?
*
By "traverse" I mean "search for a node with given value", not full tree traversal.
Yes! For a 300 000 level tree avoid recursion. Traverse your tree and find the value iteratively using a loop.
Binary Search Tree representation
25 // Level 1
20 36 // Level 2
10 22 30 40 // Level 3
.. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. // Level n
Just to clarify the problem further. Your tree has a depth of n = 300.000 levels. Thus, in the worst case scenario a Binary Search Tree (BST) will have to visit ALL of the tree's nodes. This is bad news because that worst case has an algorithmic O(n) time complexity. Such a tree can have:
2ˆ300.000 nodes = 9.9701e+90308 nodes (approximately).
9.9701e+90308 nodes is an exponentially massive number of nodes to visit. With these numbers it becomes so clear why the call stack overflows.
Solution (iterative way):
I'm assuming your Node class/struct declaration is a classic standard integer BST one. Then you could adapt it and it will work:
struct Node {
int data;
Node* right;
Node* left;
};
Node* find(int v) {
Node* temp = root; // temp Node* value copy to not mess up tree structure by changing the root
while (temp != nullptr) {
if (temp->data == v) {
return temp;
}
if (v > temp->data) {
temp = temp->right;
}
else {
temp = temp->left;
}
}
return nullptr;
}
Taking this iterative approach avoids recursion, hence saving you the hassle of having to recursively find the value in a tree so large with your program call stack.
A simple loop where you have a variable of type Node* which you set to the next node, then loop again ...
Don't forget the case that the value you are searching for does not exist!
You could implement the recursion by not using the call stack but a user-defined stack or something similar; this could be done via the existing stack template. The approach would be to have a while loop which iterates until the stack is empty; as the existing implementaion uses depth-first search, elimination of the recursive calls can be found here.
When the tree that you have is a Binary Search Tree, and all you want to do is search for a node in it that has a specific value, then things are simple: no recursion is necessary, you can do it using a simple loop as others have pointed out.
In the more general case of having a tree which is not necessarily a Binary Search Tree, and wanting to perform a full traversal of it, the simplest way is using recursion, but as you already understand, if the tree is very deep, then recursion will not work.
So, in order to avoid recursion, you have to implement a stack on the C++ heap. You need to declare a new StackElement class that will contain one member for each local variable that your original recursive function had, and one member for each parameter that your original recursive function accepted. (You might be able to get away with fewer member variables, you can worry about that after you have gotten your code to work.)
You can store instances of StackElement in a stack collection, or you can simply have each one of them contain a pointer to its parent, thus fully implementing the stack by yourself.
So, instead of your function recursively calling itself, it will simply consist of a loop. Your function enters the loop with the current StackElement being initialized with information about the root node of your tree. Its parent pointer will be null, which is another way of saying that the stack will be empty.
In every place where the recursive version of your function was calling itself, your new function will be allocating a new instance of StackElement, initializing it, and repeating the loop using this new instance as the current element.
In every place where the recursive version of your function was returning, your new function will be releasing the current StackElement, popping the one that was sitting on the top of the stack, making it the new current element, and repeating the loop.
When you find the node you were looking for, you simply break from the loop.
Alternatively, if the node of your existing tree supports a) a link to its "parent" node and b) user data (where you can store a "visited" flag) then you don't need to implement your own stack, you can just traverse the tree in-place: in each iteration of your loop you first check if the current node is the node you were looking for; if not, then you enumerate through children until you find one which has not been visited yet, and then you visit it; when you reach a leaf, or a node whose children have all been visited, then you back-track by following the link to the parent. Also, if you have the freedom to destroy the tree as you are traversing it, then you do not even need the concept of "user data": once you are done with a child node, you free it and make it null.
Well, it can be made tail recursive at the cost of a single additional local variable and a few comparisons:
Node* find(int v){
if(value==v)
return this;
else if(!right && value<v)
return NULL;
else if(!left && value>v)
return NULL;
else {
Node *tmp = NULL;
if(value<v)
tmp = right;
else if(value>v)
tmp = left;
return tmp->find(v);
}
}
Walking through a binary tree is a recursive process, where you'll keep walking until you find that the node you're at currently points nowhere.
It is that you need an appropriate base condition. Something which looks like:
if (treeNode == NULL)
return NULL;
In general, traversing a tree is accomplished this way (in C):
void traverse(treeNode *pTree){
if (pTree==0)
return;
printf("%d\n",pTree->nodeData);
traverse(pTree->leftChild);
traverse(pTree->rightChild);
}
I am talking with reference to C++.
I know that if an int is declared as static in recursion, its value is not reinitialized in stack-recursion call and the present value is used.
But if a stack becomes empty(or a recursion computation is complete) and then the recursion is called again, will it use the same static value as initialized in first stack call??
I will explain my problem in detail.
I am trying to code level order traversal in spiral form.
1
/ \
2 3
/ \ / \
7 6 5 4
Level order traversal in spiral form will give output 1 2 3 4 5 6 7.
void LevelSpiral(node* root, int level)
{
static int k = level%2;
if(root==NULL)
return;
if(level==1)
{
printf("%d ",root->val);
}
else
{
if(k==0)
{
LevelSpiral(root->left,level-1);
LevelSpiral(root->right,level-1);
}
else
{
LevelSpiral(root->right,level-1);
LevelSpiral(root->left,level-1);
}
}
}
void LevelOrderSpiral(node* root)
{
for(int i=1;i<=maxheight;i++)
LevelSpiral(root,i);
}
LevelOrderSpiral function makes separate LevelSpiral-call for each i. But throughout the code it always uses k=1(which is initialized in the first LevelSpiral-call with i=1) and prints the output as 1 3 2 4 5 6 7.
Shouldn't it print 1 2 3 4 5 6 7 as the function stack is reinitialized for every i?
You need a static variable for it's value to be retained between calls, or from one call to the next recursive call.
Furthermore, recursion wouldn't be the first tool I reach for a breadth-first traversal. I would use a queue of node (safe) pointers (or reference wrappers or whatever). Put the root node in the queue, then loop until the queue is empty removing the front element and enqueueing all of it's child nodes and do what you want with the recently removed element.
Regarding your implementation, you are alternating between going to the left first and going to the right first. level always equals 1 at the row before the one you want to print, so you always traverse your printing row from right to left. You'll see bigger shufflings of the nodes when you have a deeper tree. Draw a sample tree on paper and draw the navigations on it as you follow your code by hand.
I know that if an int is declared as const in recursion, its value is not reinitialized in stack-recursion call and the present value is used.
No, that’s wrong. const has got nothing to do with recursion or reentrancy.
But if a stack becomes empty(or a recursion computation is complete) and then the recursion is called again, will it use the same const value as initialized in first stack call??
A const is a normal (albeit unmodifiable) variable: it is reinitialised whenever the initialisation statement is executed, i.e. on every function call. This is the same for any non-static variable.
static local variables exhibit the behaviour you are describing: they are only executed once, at the first call of that function, and, importantly, they are not reinitialised even after the call stack is “emptied”. It makes no difference whether the function is called repeatedly from outside, or recursively.
I'm using a library written in C and the library provides headers which only use void*. The library is used to create a kind of graph, which is stored inside the C data-base. The headers return void* to the nodes in the graph. To create the graph, I need to parse a stack of lets say node names. In parallel to the stack of node names, I need to maintain a stack void* for the nodes. I have something like this:
std::stack < void* > nodeStack;
while (!nodeNameStack.empty()) {
// check if nodeNamestack.front() meets some criteria
nodeStack.push(C_API_To_Create_Node(nodeNameStack.pop()));
// Do some processing
// check if nodeStack.size() >= 2
void *node1 = nodeStack.pop()
void *node2 = nodeStack.pop()
// Above line issues error saying void value not ignored as it ought to be..
I'm not sure what the issue is, as we guarantee nodeStack size is atleast 2. I would appreciate any suggestions to overcome this error..
std::stack::pop() doesn't return the element removed. You have to read it with top() before popping it.
2 Things
A) you forgot ;'s after nodeStack.pop().
B) .pop() returns void which is why you are getting the error. .pop() just removes the element from the stack. Use .top() to get the element, then .pop() to remove it.
The prototype for stack::pop is
void pop ( );
Therefore it does not return anything hence the warning. Perhaps you meant to use stack::top