pass bool variable by reference in function argument - c

I am trying to include a boolean flag in the below function argument to see whether a value already exists in the current tree structure of values.
VLTreeNode *addNewNode(AVLTreeNode *currentNode, int k, int v, bool *ifExist)
{
if (currentNode == NULL)
{
return newAVLTreeNode(k, v);
}
if (k == currentNode->key && v == currentNode->value)
{
*ifExist = true;
return currentNode;
}
else if ((k == currentNode->key && v < currentNode->value) || k < currentNode->key)
{
currentNode->left = addNewNode(currentNode->left, k, v, &ifExist);
currentNode->left->parent = currentNode;
}
else if ((k == currentNode->key && v > currentNode->value) || k > currentNode->key)
{
currentNode->right = addNewNode(currentNode->right, k, v, &ifExist);
currentNode->right->parent = currentNode;
}
}
The call of this function would be like the following:
bool ifExist = false;
Tree->root = addNewNode(Tree->root, k, v, &ifExist);
if (ifExist)
{
T->size++;
}
and it does not work... could someone give me some hints what goes wrong in the code. Much appreciated.

In addNewNode, in your last two else if blocks, you're passing in &ifExist. But ifExist is a bool* already, should just pass in ifExist.
I'm not sure, but It's possible that the return statements only in the first if blocks is ok so long as those cover all possible base cases of your recursive function. [I was not thinking straight, the return statements are definitely necessary in all branches - I meant that setting ifExist to true is only required in the base cases...]
But yeah, the passing ifExist by reference (effectively now bool **) inside addNewNode is definitely not right.
EDIT: To clarify, in your outermost call to addNewNode where you have...
bool ifExist = false;
Tree->root = addNewNode(Tree->root, k, v, &ifExist);
...you do need to pass in by reference.
But inside addNewNode, your last two if else blocks should be
else if ((k == currentNode->key && v < currentNode->value) || k < currentNode->key)
{
currentNode->left = addNewNode(currentNode->left, k, v, ifExist);
currentNode->left->parent = currentNode;
}
else if ((k == currentNode->key && v > currentNode->value) || k > currentNode->key)
{
currentNode->right = addNewNode(currentNode->right, k, v, ifExist);
currentNode->right->parent = currentNode;
}
I would advise doing instead:
bool exists = false;
bool * ifExist = &exists;
Tree->root = addNewNode(Tree->root, k, v, ifExist);
That way, the way addNewNode arguments look is consistent everywhere... which will prevent future arcidents due to copy paste.

Related

How can I make this code smaller, without 3 loops? I should find 3 students with the smallest marks

I have to make my lab))
In general, I should find the index of three students with the smallest rating points.
How I can do it without three loops? Just by one.
In this function, I use structures and output arguments.
int addDelateThree(stud** pListHead, int* Imin, int* Jmin, int* Cmin) {
stud* pTemp = pListHead;
stud* SpTemp = pListHead;
stud* TpTemp = pListHead;
int check = 0;
double min1 = pTemp->madian;
double min2 = SpTemp->madian;
double min3 = pTemp->median;
int i = 0;
while (pTemp != NULL) {
if (min1 > pTemp->madian) {
min1 = pTemp->madian;
*Imin = i;
}
i++;
pTemp = pTemp->next;
}
i = 0;
while (SpTemp != NULL) {
if (min2 > SpTemp->madian && i != *Imin) {
min2 = SpTemp->madian;
*Jmin = i;
}
i++;
SpTemp = SpTemp->next;
}
i = 0;
while (TpTemp != NULL) {
if (min3 > TpTemp->madian && i != *Imin && i != *Jmin) {
min3 = TpTemp->madian;
*Cmin = i;
}
i++;
TpTemp = TpTemp->next;
}
}
Make a list of 3 stud *. Initialize all to point to a dummy record whose .madian = INFINTY;
Walk the linked list once.
Compare node's .madian to list[2]->madian. If <=, adjust list of 3 with new minimal .madian. This may involve several compares as code compares 1st the greatest min value, then next greatest min and finally the least value.
Report result.
O(n) solution.

Need to decrement a counter in a recursive tree function, but only when I am moving "upwards" in the tree

I am writing a recursive function to find if there is a path from the root to a leaf that sums up to a certain number or not (user inputs the sum). Each time I move forward into a new recursive call, I increment the value of current_sum with the value of node->data. Current_sum is declared/initialized outside of the function. So this works fine to get the sum to the left-ermost leaf. However after that, the current_sum just keeps increasing, as I don't have an appropriate decrement operation to go with it. So if there does exist a path that adds up to a certain number in the righter branches, for example: 1 2 # # 3 # #, and I check for path sum = 4, (1+3), it would not get that. (If i check for sum=3 (1+2), it does get it.)
So I am looking for the correct place in my code to put the decrement operation. I was thinking something like: current_sum -= root->data. However I've tried putting it a lot of different places, but all of them seem to be wrong places. Either they disrupt the original tracker to get to even the very first leftermost leaf. Or they don't decrement at all (if I put it after the both the left/right recursive calls). I also do need it to keep decrementing while it goes UP but increment while it goes DOWN. Is there a way to write this in code, I am curious? Or, is this just a bad algorithm/approach?
I've seen other ways of solving this problem, such as https://www.geeksforgeeks.org/root-to-leaf-path-sum-equal-to-a-given-number/, which seem really nice, I just wanted to know if there was a way to resolve the one I started.
int current_sum = 0;
int sumPath(Node * root, int sum)
{
if (root == NULL)
{
return 0;
}
current_sum += root->data;
if ((root->left == NULL) && (root->right == NULL))
{
if (current_sum == sum)
{
return 1;
}
else
{
return 0;
}
}
int the_left = sumPath(root->left, sum);
int the_right = sumPath(root->right, sum);
////////////////////current_sum -= root->data; (?)
if (the_left>0)
{
return the_left;
}
else if (the_right>0)
{
return the_right;
}
return 0;
}
You may get invalid output, because of not sending current_sum as a parameter. Because current_sum needs to be updated for a particular stack-trace or function call, not for commonly for all the function calls. and this may give you an invalid state.
UPDATE
int isPossible(Node * root, int currentSum, int sum) {
if(!root) return 0;
currentSum += root.node;
// when you find the sum, and can't move further down
if(sum == currentSum && root->left == null && root->right == null) return 1;
int flag = 0;
// going down on left side
flag = isPossible(root->left, currentSum, sum);
// needs to check right side, only when you couldn't find sum on left
if(!flag)
flag = isPossible(root->right, currentSum, sum);
// return the state
return flag;
}
your code is fine, u just need to pass sum - current_sum in the recursive call. This is your code with some hinted modifications.
#include <stdio.h>
// remove global current_sum
struct Node {
char* name;
int data;
struct Node* left;
struct Node* right;
};
int sumPath(struct Node* root, int sum) {
if (root == NULL) {
return 0;
}
if ((root->left == NULL) && (root->right == NULL)) {
if (current_sum == sum) {
printf("%s ", root->name); // if the branch matches, print name
return 1;
} else {
return 0;
}
}
int the_left = sumPath(root->left, sum - root->data); // pass the subtracted sum
int the_right = sumPath(root->right, sum - root->data); // pass the subtracted sum
if (the_left > 0) {
printf("%s ", root->name); // if the branch matches, print name
return the_left;
} else if (the_right > 0) {
printf("%s ", root->name); // if the branch matches, print name
return the_right;
}
return 0;
}
int main() {
struct Node n1 = {.data = 1, .name = "n1"}; // n1
struct Node n2 = {.data = 1, .name = "n2"}; // ___|___
struct Node n3 = {.data = 1, .name = "n3"}; // | |
struct Node n4 = {.data = 1, .name = "n4"}; // n2 n4
// ___|
n1.left = &n2; // |
n1.right = &n4; // n3
n2.left = &n3; //
sumPath(&n1, 3); // no. of steps including the root
return 0;
}
// output
// n3 n2 n1

Recursing through a AST using DFS

I am trying to recurse through an annotated syntax tree.
My aim is to increment a counter once it sees a particular type of node.
Void *DFS(State *N, IrNode *node, int Counter)
{
Counter=0
if (node->irLeftChild == NULL &&
node->irRightChild == NULL &&
node->isVisited == false &&
node->type == kNewtonIrNodeType_Tidentifier)
{
Counter+=1
node->isVisited = true;
return ;
}
DFS(N, node->irLeftChild);
DFS(N, node->irRightChild);
}
Is there a better way to recurse through the tree?
I'm not sure what you're trying to do; but if you're trying to return a total count of entries that matched the criteria to the caller you probably want something like:
int DFS(State *N, IrNode *node) {
int Counter = 0;
if (node->irLeftChild == NULL && node->irRightChild == NULL && node->isVisited == false && node->type == kNewtonIrNodeType_Tidentifier) {
Counter += 1;
node->isVisited = true;
}
Counter += DFS(N, node->irLeftChild);
Counter += DFS(N, node->irRightChild);
return Counter;
}

Understand the processed state in the BFS implementation of the Algorithm Design Manual (Second Edition)

In the notes to the implementation of BFS, the book says "A vertex is considered processed after we have traversed all outgoing edges from it", which is contradict to the given implementation:
bfs(graph *g, int start)
{
queue q;
int v;
inv y;
edgenode *p;
init_queue(&q);
enqueue(&q, start);
discovered[start] = TRUE;
while (empty_queue(&q) == FALSE)
{
v = dequeue(y);
processed[v] = TRUE;
p = g->edges[v];
while (p != NULL)
{
y = p->y;
if ((process[y] == FALSE) || g->undirected)
{
process_edge(v, y);
}
if (discovered[y] == FALSE)
{
enqueue(&q, y);
discovered[y] = TRUE;
parent[y] = v;
}
p = p->next;
}
}
}
Shouldn't the processed[v] = TRUE; be placed after the while loop?
In the context of this implementation, if the graph has self-loops, it will process edge (v, v) for some v. Of course, we can move the processed[v] = TRUE;, after the while loop, but in this case we should carefully treat self-loops(resulting in more code).

Counting the sign changes in a list in C

I have to get the number of sign changes in a list of doubles. For example if there is a list like that: "1, -1, -1, 1" there are 2 sign changes, between the adjacent elements. I tried it like this but for some reason the program crashes if I try to compile it:
int number_of_sign_changes(DoubleList* list) {
int changes = 0;
for (DoubleNode *n = list->first; n != NULL; n = n->next) {
if ((n->value >= 0) && (n->next->value < 0)) {
changes += 1;
} else if ((n->value < 0) && (n->next->value >= 0)) {
changes += 1;
}
}
return changes;
}
The loop definitely works. I tried it in other functions but here it won't work. Does anyone have an idea? Btw you could actually put the 2 if statements into 1 and I tried that aswell but same problem.
This is in essence a fence post problem. The number of possible sign changes is one less than the number of elements in the list, so as you are checking on each item, you can tell you are doing something wrong. The problem in fact occurs when checking the last item on the list - it attempts to check for a sign change to the 'next' item, and there isn't one, as n->next is NULL.
This can be fixed by a simple change to the terminating condition in the for loop as follows:
int number_of_sign_changes(DoubleList* list) {
int changes = 0;
for (DoubleNode *n = list->first; n != NULL && n->next != NULL; n = n->next) {
if ((n->value >= 0) && (n->next->value < 0)) {
changes += 1;
} else if ((n->value < 0) && (n->next->value >= 0)) {
changes += 1;
}
}
return changes;
}

Resources