Form flag with 3 nodes in a binary tree - c

I have a binary tree with nodes colored either in green, white or red. The function returns 1 if it finds a path of three nodes that form the italian flag, 0 otherwise. 
This is what I've tried but it gives me segmentation fault.
struct node{
char color;
struct node* left;
struct node* right;
struct node* father;
};
typedef struct node* Node;
int flag(Node v){
if(v==NULL)
return 0;
flag(v->left);
flag(v->right);
if(v->color=='W' && v->father->color=='G' && (v->left->color=='R' || v->right->color=='R'))
return 1;
}
EDIT: Thanks to all for answering. This should be the correct version
int flag(Node v){
if(v==NULL)
return 0;
if(v->left && v->father)
if(v->color=='B' && v->father->color=='V' && v->left->color=='R')
return 1;
if(v->right&& v->father)
if(v->color=='B' && v->father->color=='V' && v->right->color=='R')
return 1;
return flag(v->left) || flag(v->right);
}

The problem is probably that you call flag with invalid pointer v->left or v->right.
Probably you did not initialize with NULL the node fields.
Other problem is that if any of v->left or v->right is NULL you still try to access v->left->color in the last composed condition.
Other error is that you do not explicitly return a value in case that the last combination is false. If
v->color=='W' &&
v->father->color=='G' &&
(v->left->color=='R' || v->right->color=='R')
is false, you do not return a value at the end of the function.

You might have NULL pointers...
if(v->color=='W' && v->father->color=='G' && (v->left->color=='R' || v->right->color=='R'))
You do not check if v->left or v->right are NULL before you dereference them. For the root node also v->father could be NULL.
You should also add an else part returning 0.
Besides that:
For which purpose do you call flag(v->left) and flag(v->right) if you don't care about the return value?

int flag(Node v)
{
if(v==NULL)
return 0;
flag(v->left); // <<-- this call will return when v->left is NULL
flag(v->right); // <<-- this call will return when v->right is NULL
//so, if you come till here in case 'v' is leaf then (v->left is NULL) and (v->right is NULL)
//but you are accessing them as 'v->left->color' and 'v->right->color'
//that is accessing 'NULL->color' is bound to break.
if(v->color=='W' && v->father->color=='G' && (v->left->color=='R' || v->right->color=='R'))
return 1;
}

Related

The least node that is greater than or equal to a given value in AVL

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".

Linked list: how to make sorter checker in C?

I thought this should work correctly...I'm not sure what's wrong with it? Here's a snippet of my code. It's suppose to return 0 if the given list of integers are not in ascending order and return 1 if it is in ascending order.
struct Node{
int data;
Node *pNext;
};
int isItSorted(Node *pHead){
while(pHead != NULL){
if(pHead->data > pHead->pNext->data)
return 0;
else
return 1;
pHead = pHead->pNext;
}
return 1;
}
You invoke undefined behavior, as #Dai said, when you do pHead->pNext->data without first checking pHead->pNext != NULL. Additionally, as #JohnBollinger said, you have a return 1 inside the while, so it will return after checking list[0] < list[1] instead of going through the entire thing.
struct Node{
int data;
Node *pNext;
};
int isItSorted(Node *pHead){
while(pHead != NULL && pHead->pNext != NULL) { // 0 and 1 element lists are always sorted, so this is fine.
if(pHead->data > pHead->pNext->data)
return 0; // Break out and return
else
pHead = pHead->pNext; // Or keep going
}
return 1; // Lift out end case from loop
}
Here's a tail-recursive version, too: (EDIT: Neither clang nor gcc appear to be smart enough to notice the tail-recursion, even with -O3. Oh well.)
int isSorted(Node *list) {
return list == NULL // [] is sorted
|| list->pNext == NULL // [x] is sorted
|| list->data <= list->pNext->data && isSorted(list->pNext); // x:y:z is sorted if x < y and y:z is sorted
}
This is your (major) problem:
if(pHead->data > pHead->pNext->data)
return 0;
else
return 1;
Doing this inside your loop will return one or zero immediately, based only on the comparison of the first two items. That's assuming you have at least two items in there, otherwise you have undefined behaviour because you dereference the null pointer.
I would implement it as follows (pseudo-code), with plain checks up front to catch the edge cases (less than two items), and continuing to check items for ordering rather than returning after a single check:
def isSorted(head):
# Less than two items means sorted no matter what the data is.
if head == NULL:
return true
if head.next == NULL:
return true
# Continue while there are at least two items to check.
node = head
while node.next != NULL:
# If those two items out of order, it'snot sorted.
# If they are in order, advance and keep checking.
if node.data > node.next.data:
return false
node = node.next
# Reaching here means all items were in order.
return true
Just one mistake in your code:
struct Node{
int data;
Node *pNext;
};
int isItSorted(Node *pHead){
while(pHead != NULL){
if(pHead->next != NULL && pHead->data > pHead->pNext->data) {
return 0;
}
pHead = pHead->pNext;
}
return 1;
}
whenever dealing with loops, make sure you check your exit conditions.
For example, in your code, if it is not going into the IF block, then it is bound to return 1. and your loop iteration will never repeat.
So that's all. Make sure you think about your EXIT conditions while dealing with loops.

Number of leaves in binary search tree in C

I am a beginner and working on a C binary search tree.I am trying to do a method that will return the number of leaves in my tree.By leaves I mean a node(parent) that has no child(left/right) Heres my tree struct:
struct Node {
int value;
struct Node *left;
struct Node *right;
};
typedef struct Node TNode;
typedef struct Node *binary_tree;
It is created like this:
binary_tree NewBinaryTree(int value_root) {
binary_tree newRoot = malloc(sizeof(TNode));
if (newRoot) {
newRoot->value = value_root;
newRoot->left = NULL;
newRoot->right = NULL;
}
return newRoot;
}
I add elements to it like:
void Insert(binary_tree *tree, int val) {
if (*tree == NULL) {
*tree = (binary_tree)malloc(sizeof(TNode));
(*tree)->value = val;
(*tree)->left = NULL;
(*tree)->right = NULL;
} else {
if (val < (*tree)->value) {
Insert(&(*tree)->left, val);
} else {
Insert(&(*tree)->right, val);
}
}
}
My actual method to count the number of leaves:
int nbleaves(binary_tree tree)
{
int nb;
if(tree->right==NULL && tree->left ==NULL){
nb=nb+1;
}
printf("%d",nb);
}
Of course this doesnt work first theres no actual loop,however I tried it it doesnt return any error but 0(ex after adding element 2222 and 3 to the tree this function return 0).I dont know how to do this function.
thank you!
Because you MUST initialize nb.
int nb = 0;
Since nb is uninitialized it contains a "random" or "garbage" value so the behavior you see is because that value can be very large. But there is no way to predict what that value is.
NOTE: Don't be "stingy" with white spaces, don't use too many of them but let your code breath a little.
Compare
if(tree->right==NULL && tree->left ==NULL){
nb=nb+1;
}
with
if ((tree->right == NULL) && (tree->left == NULL)) {
nb = nb + 1;
}
Besides initializing as #iharob pointed out, you just need to recurse on the left and right halves of the tree and add that to your total (as said in the comments). This approach worked for me on my tests so I'm not sure what error you're getting when you tried it. Here's my nbleaves() function:
int nbleaves(binary_tree tree)
{
int nb=0;
if(tree->right==NULL && tree->left ==NULL){
nb=nb+1;
}
else {
if(tree->left!=NULL)
nb += nbleaves(tree->left);
if(tree->right!=NULL)
nb += nbleaves(tree->right);
}
return nb;
}
For example, on this test case:
int main() {
binary_tree root=NULL;
root=NewBinaryTree(5);
Insert(&root,3);
Insert(&root,7);
Insert(&root,2);
Insert(&root,8);
Insert(&root,6);
Insert(&root,1);
Insert(&root,4);
Insert(&root,9);
traverse(root); /*Just a function I created for testing*/
printf("%d\n",nbleaves(root));
free_tree(root); /*Also a function I wrote*/
return 0;
}
It produces this output:
5: 3 7
3: 2 4
2: 1 NULL
1: NULL NULL
4: NULL NULL
7: 6 8
6: NULL NULL
8: NULL 9
9: NULL NULL
4
The last line is the leaves count and the rest are outputs of traverse().
For my full program: https://repl.it/Epud/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;
}

Is a Binary Tree Contained Within Another Binary Tree - C

So I just had an interview that I'm confident I screwed up royally. I had a bunch of questions thrown at me and didn't have enough time to answer the last one.
After getting all beginning questions correct, I was asked to write a function that would determine whether a binary tree b is contained within another binary tree a. I coded the question prior to that correctly, in which he asked me to write a function to determine whether two trees are equal:
int sameTree(struct node *a, struct node *b){
//both empty = TRUE
if(a == NULL && b == NULL)
return TRUE;
//both not empty, compare them
else if(a != NULL && b != NULL){
return(
a->data == b->data &&
sameTree(a->left, b->left) &&
sameTree(a->right, b->right)
);
}
//one empty, one not = FALSE
else
return FALSE;
}
Ugh. Just for clearing my conscience, again how would you determine whether tree b is inside tree a?
Thanks for any help guys.
int in(struct node* outer, struct node* inner){
if(inner == null){
return true; // say every tree contains the empty tree
} else if(outer == null){
return false;
} else if(same(outer, inner)){
return true;
} else return in(outer->left, inner) || in(outer->right, inner);
}
We must not use the OP's sameTree but rather this function:
int same(struct node* outer, struct node* inner){
return !inner || outer && outer->data == inner->data && same(outer->left, inner->left) && same(outer->right, inner->right);
}
Or, more verbosely,
int same(struct node* outer, struct node* inner){
if(inner == null){
return true;
} else if(outer == null){
return false;
} else if(outer->data == inner->data){
return same(outer->left, inner->left) && same(outer->right, inner->right);
} else return false;
}
This assumes you want the same tree with the same structure, contains in a:
For one, if b is null and a isn't, a contains b (you should check that in your last else).
Second, these aren't binary search trees (unsorted), so to check if b is inside a you should also traverse a (assuming you rename the function):
int containsTree(struct node *a, struct node *b){
//both empty = TRUE
if(a == NULL && b == NULL)
return TRUE;
//both not empty, compare them
else if(a != NULL && b != NULL){
return(
// sameTree should be changed to allow nulls, as below
sameTree(a, b)
// check recursively
|| containsTree(a->left, b)
|| containsTree(a->right, b)
);
//one empty, one not = FALSE
else
return B == NULL;
To check if tree A is contained as-is in tree B, find the node C in B such that C.data == A.data. If there is no such node, A is not contained in B. If C exists, check if A and C are equal using a modified sameTree function - one that ignores mismatches between null children of A and non-null children of C (return true if A.left/right is null).
Thanks #Kobi for the correction.

Resources