C function to count amount of same Parent Child values - c

i'm working new with binary tree and just trying to write this Function,
which give the number of node with the same Parent value, the problem with my code that it
give 0 as result or wrong number!
int x=0;
int amountSameParentChild(TreeNode *node){
if((node!=NULL) && (node->left!=NULL || node->right!=NULL)){
if (node->data==node->left->data||node->data==node->right->data){
x++;
amountSameParentChild(node->left);
amountSameParentChild(node->right);
}
}
return x;
}
int main()
{
int upperLimit = 10;
int entries[upperLimit];
int *results = malloc(sizeof(int));
srand(time(NULL));
for (int i = 0; i < upperLimit; i++)
{
int randomEntry = rand() % (5);
entries[i] = randomEntry;
}
TreeNode *root = newNode(0);
root = createRandomTree(entries, root, 0, upperLimit);
printAsTree(root, 10);
printf("%d\n", amountSameParentChild(root));
}

int amountSameParentChild( TreeNode *node ) {
return 0;
}
By definition, the answer will always be zero...
By definition, values of all 'left subtree' nodes are LESS THAN the parent/root node, and 'right subtree' values GREATER THAN.
No child node can/will have the same value as its parent...

Related

How do implement Count sort using linked list?

What I am trying to do is to create a counting sort using a linked list so I can link two similar elements in the same index and then copy from left to right to the original array. But my Buckets[i] are always NULL even after insertion. So my resulting array does not change. I don't know what I am doing wrong.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
} **Buckets;
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
int findMax(int A[], int n) {
int i, max = A[0];
for (i = 0; i < n; i++) {
if (A[i] > max)
max = A[i];
}
return max;
}
void Insert(struct Node *p, int x) {
while (p != NULL) {
p = p->next;
}
Node *t = t = (struct Node *)malloc(sizeof(struct Node));
t->data = x;
t->next = NULL;
p = t;
}
int Delete(struct Node *Buckets) {
while (Buckets->next != NULL) {
Buckets = Buckets->next;
}
int temp = Buckets->data;
free(Buckets);
return temp;
}
void BucketSort(int A[], int size) {
int max, i, j;
max = findMax(A, size);
Buckets = new Node * [max + 1];
for (i = 0; i < max + 1; i++) {
Buckets[i] = NULL;
}
for (i = 0; i < size; i++) {
Insert(Buckets[A[i]], A[i]); //insertion
}
i = j = 0;
while (i < max + 1) {
while (Buckets[i] != NULL) {
A[j++] = Delete(Buckets[i]); // copy back in array
}
i++;
}
}
int main() {
int arr[] = { 3, 8, 5, 1, 10 };
int size = sizeof(arr) / sizeof(arr[0]); //5
printf("\nBefore : ");
printArray(arr, size);
BucketSort(arr, size);
printf("\nAfter : ");
printArray(arr, size);
return 0;
}
Your Insert function doesn't really modify the list – you just assign the new node to a local variable, which goes out of scope immediately.
You can solve this by passing a pointer to a node pointer to the function. That pointer points at the head pointer at first and at the next member of the preceding node when you advance:
void Insert(struct Node **p, int x)
{
while (*p) p = &(*p)->next;
*p = new Node(x); // assume a c'tor here
}
Call the function like so:
for (i = 0; i < size; i++) {
Insert(&Buckets[A[i]] ,A[i]);
}
The same goes for deletion: You must modify the links or the list head when you delete:
int Delete(struct Node **p)
{
int temp = (*p)->data;
struct Node *del = *p;
*p = (*p)->next;
delete del;
return temp;
}
(This code extracts the head node, which is probably what you want: You insert at the end, then retrieve from the beginning. That should preserve the original order. Not that it matters miuch in your case, where you have no data beside the int.)
Call Delete like so:
i = j = 0;
while (i < max + 1) {
while (Buckets[i]) {
A[j++] = Delete(&Buckets[i]);
}
i++;
}

How to get length of the longest prefix in Trie in C

I'm trying to figure out how to find the length of the longest prefix of two words in Trie. I was trying to find a solution, but I found nothing.
I already have an implementation of Trie, where the nodes are represent by structure:
struct node
{
int end; // 1 if node is end of word or 0 if not
int count; // The number of words that contain current node
struct node *letter[26]; // Array of nodes, which represent the alphabet
};
int length_of_longest_prefix(struct node *root)
{
//??????????
}
I tried to make a recursive function for this problem, but I could not do it.
Let´s think about this filled trie:
Filled trie
What is the best way to solve this problem?
Pseudocode will be very usefull.
My function:
//Global variable
int total_max;
//root = start
int length_of_longest_prefix(struct node *root, struct node *start)
{
int max = 0;
int depth = 0;
for (int i = 0; i < 26; i++)
{
if(root->letter[i] != NULL && root->letter[i]->count >= 2)
{
depth = length_of_longest_prefix(root->letter[i], start);
depth++;
if(root->letter[i] == start->letter[i])
{
depth = 0;
}
}
if(depth > total_max)
total_max = depth;
}
return depth;
}
int main(void)
{
total_max = 0;
struct node *root = (struct node*)malloc(sizeof(struct node));
for (int i = 0; i < 26; i++)
{
root->letter[i] = NULL;
}
root->end = 0;
root->count = 0;
/*Inserting strings to Trie*/
length_of_longest_prefix(root, root);
printf("%d\n", total_max);
return 0;
}

Sum of elements on the way to largest leaf in BST

I am trying to sum all the nodes on the way to the largest leaf in a binary search tree. The nodes contain only positive numbers.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>
typedef int ElType;
typedef struct Tree {
ElType key;
struct Tree *left;
struct Tree *right;
} Tree;
Tree* InsertBST(Tree* t, int k)
{
if (t == NULL) {
Tree* w = (Tree*) malloc(sizeof(Tree));
w->key = k;
w->left = NULL;
w->right = NULL;
return w;
}
if (k <= t->key)
t->left = InsertBST(t->left, k);
else
t->right = InsertBST(t->right, k);
return t;
}
int SumMaxOfBST(Tree* t, int *sum_max)
{
if (t == NULL) {
*sum_max = -1;
return *sum_max;
}
if (t->right == NULL) {
*sum_max += t->key;
return *sum_max;
}
*sum_max += t->key;
*sum_max += SumMaxOfBST(t->right, sum_max);
return *sum_max;
}
int main()
{
int i;
srand (time(NULL));
Tree* t = NULL;
for (i = 0; i < 20; i++)
t = InsertBST(t, rand() % 1000);
int sum_way = 0;
int a = SumMaxOfBST(t, sum_way);
printf("Sum on the way to the largest leaf %d:\n", a);
return 0;
}
This exits with non-zero status. My strong suspicion is that I have botched the use of pointers, however, after several rewrites and videos on the use of pointers I still don't seem to grasp what's going on. If I understand correctly,*sum_max += x should increment the value of sum_max by x. At which point is my use of pointers off?
I don't get why you take a pointer to int as a paramter for SumMaxOfBST, I think the function written like this is simpler.
int SumMaxOfBST(Tree* t)
{
if (t == NULL) {
return 0;
}
if (t->right == NULL) {
return t->key;
}
return t->+key + SumMaxOfBST(t->right);
}
Furthermore in your main, you're passing sum_way that is an int, while SumMaxOfBST expects an int*. You should pass &sum_way instead.

Find sum of shortest root to leaf path in a binary tree

I am trying to implement a function which will return the sum of the shortest path in a binary tree. I am getting the incorrect answer of 8 instead of 4 for the following tree.
1
/ \
2 3
/ \
4 5
int sumOfShortestPath(BinaryTreeNode *root, std::vector<int> vec) {
if(!root) return 0;
static int minPathLength = INT_MAX;
static int pathLength = 0;
static int sum = 0;
vec.push_back(root -> data);
pathLength++;
if(root -> left == NULL and root -> right == NULL) {
if(pathLength < minPathLength){
minPathLength = pathLength;
sum = sum_vector(vec);
pathLength = 0;
}
}
sumOfShortestPath(root -> left, vec);
sumOfShortestPath(root -> right, vec);
return sum;
}
I believe my logic is correct but i'm unsure where i'm going wrong. Basically, if I encounter a smaller path, I update minPathLength and sum and reset pathLength back to 0 for the next path exploration.
You're kind of on the right track, but I think the static variables are tripping you up some here. Also, I don't see a reason to keep a list of the values. You only need just enough information to determine if the left or right branches are the shortest.
Here's my revised version:
#include <stdio.h>
class node
{
public:
node *left, *right;
int value;
node (int v) : left(nullptr), right(nullptr), value(v) { }
};
int sumOfShortestPath(node *root, int *cnt)
{
if (!root)
{
*cnt = 0;
return 0;
}
int lcnt;
int rcnt;
int lsum = sumOfShortestPath(root->left, &lcnt);
int rsum = sumOfShortestPath(root->right, &rcnt);
if (lcnt < rcnt)
{
*cnt = lcnt + 1;
return root->value + lsum;
}
else
{
*cnt = rcnt + 1;
return root->value + rsum;
}
}
node *buildTree()
{
node *root = new node(1);
root->right = new node(3);
root->left = new node(2);
root->left->left = new node(4);
root->left->right = new node(5);
return root;
}
void main(void)
{
node *tree = buildTree();
int work = 0;
int val = sumOfShortestPath(tree, &work);
printf("Result: %d\r\n", val);
}
There are probably much more optimal ways of counting tree lengths than this, but this gets the job done at the end of the day.

Linked list of "random" values, program hangs

I'm trying to learn C a little bit and am dealing with linked lists right now. I have defined a linked list as:
struct data {
int xVal;
int yVal;
struct data *next;
};
What I want to do is insert num pairs of values into the linked list, but each pair must be unique.
void addToList(num) {
srand(time(NULL));
struct data *list = NULL;
list = malloc(sizeof(struct data));
struct data *q = list;
list->xVal = rand() % 100;
list->yVal = rand() % 100;
int j = 0;
while (j < num-1) {
q->next = malloc(sizeof(struct data));
q->next->xVal = rand() % 100;
q->next->yVal = rand() % 100;
if (unique(list, q->next->xVal, q->next->yVal)) {
q = q->next;
j++;
}
}
}
bool unique(struct data *list, int x, int y) {
struct data *q = list;
while (q->next != NULL) {
if (q->xVal = x && q->yVal == y) { return false; }
q = q->next;
}
return true;
}
What it does is it generates a random value 1-100 for both xVal and yVal, checks if that pair already exists in the list, and if not it inserts at the end. It compiles fine, but running the program makes it hang. I don't see any infinite loops here. I've tried with num equal to 2 and it still hangs.
Removing the check for unique values lets me fill and print the list, but I still run into an exception "Access violation reading location 0xCDCDCDD9.".
Problem
You have a logic error.
You add couple of values to the list using:
q->next->xVal = rand() % 100;
q->next->yVal = rand() % 100;
and then check whether they exist in the list. Of course they do. The return value from unique is always false. As a consequence, j never gets incremented and the list keeps growing despite j not being incremented.
Fix
Get the random numbers.
Check whether they are unique before adding them to the list.
Here's how I see it.
void addToList(num) {
srand(time(NULL));
struct data *list = NULL;
list = malloc(sizeof(struct data));
struct data *q = list;
list->xVal = rand() % 100;
list->yVal = rand() % 100;
int j = 0;
while (j < num-1) {
int x = rand() % 100;
int y = rand() % 100;
if ( unique(list, x, y) ) {
q->next = malloc(sizeof(struct data));
q->next->xVal = x;
q->next->yVal = y;
q->next->next = NULL; // Make sure the list has a clean end
q = q->next;
j++;
}
}
}
And ...
You also have a typo in unique.
if (q->xVal = x && q->yVal == y) { return false; }
should be:
if (q->xVal == x && q->yVal == y) { return false; }
// ^^ Need to compare, not assigh.

Resources