I am working with the following code I found on here to begin my project that involves a tree data structure.
struct node{
int ID;
struct node* next;
struct node* child;
};
typedef struct node node;
node* new_node(int);
node* add_sibling(node*, int);
node* add_child(node*, int);
int main()
{
int i;
node *root = new_node(0);
for (i = 1; i <= 3; i++)
add_child(root, i);
}
node * new_node(int ID)
{
node* new_node =(node*) malloc(sizeof(node));
if (new_node) {
new_node->next = NULL;
new_node->child = NULL;
new_node->ID = ID;
}
return new_node;
}
node* add_sibling(node* n, int ID)
{
if (n == NULL)
return NULL;
while (n->next)
n = n->next;
return (n->next = new_node(ID));
}
node* add_child(node* n, int ID)
{
if (n == NULL)
return NULL;
if (n->child)
return add_sibling(n->child, ID);
else
return (n->child = new_node(ID));
}
I am a beginner with C/C++ and programming in general. I think I understand everything about the code except for the add_child function. The function seems to return a pointer to a node, but when it is called in main, it seems to be called as though it were a void function. I would have thought to call the function this way
*root = add_child(root,i);
like how new_node is called, or to write add_child as a void function, but both of these modifications results in errors (not to mention the implementation in the code I found does work). What am I missing?
This function rewritten will look like following.
node* add_child(node* n, int ID)
{
// For null pointer return null
if (n == NULL)
{
return NULL;
}
// If element has child add a sibling to that child
if (n->child)
{
node* sibling_for_child = add_sibling(n->child, ID);
return sibling_for_child;
}
else
{
// Otherwise just add element as a child
node* child_node = new_node(ID);
n->child = child_node;
return child_node;
}
}
The result of assignment is an assigned value(*) like in this chaining assignment:
int a, b;
a = b = 3;
which is actually:
a = (b = 3);
or
b = 3;
a = b;
Related
I am making a program to test out binary search trees in the c language. I want to balance it using a less good array method. I dynamically allocate the array based on the number of nodes in the BST and send the array off to another function that does the search and should place the elements in the array. However, when I run the program just the first element (the root of the tree) shows up in the array with every other iteration nothing happens. I am not sure on what is wrong.
Below is a MCVE for the part of the program that does not work. The first code blocks are simply to make and fill a BST. And it's the sorterToArray function that does not work.
In the recursive function sorterToArray I have tried to send the next place in the array but that does not work since it "is a nullptr".
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct treeNode
{
int data;
struct treeNode* left;
struct treeNode* right;
};
typedef struct treeNode* BSTree;
void insertSorted(BSTree* tree, int data);
void sorterToArray(struct treeNode* temp, int* pArray, int i);
int counter(int i, const BSTree tree);
void goLeftAndRight(struct treeNode* newNode, struct treeNode* tempTree, const int data);
void balanceTree(BSTree* tree);
static int* writeSortedToArray(const BSTree tree);
int main(void) {
BSTree tree = NULL;
insertSorted(&tree, 10);
for (int i = 0; i < 9; i++)
insertSorted(&tree, i + 20);
balanceTree(&tree);
}
static struct treeNode* createNode(int data)
{
//Creates the new node for the tree
struct treeNode* newNode;
//Allocates memory for the new node
newNode = calloc(1, 1 + sizeof(struct treeNode*));
//Tests the new memory
assert(newNode != NULL);
//Assigns data to the new node
newNode->data = data;
//Sets the left and right pointers to NULL so that other functions know where the ends are
newNode->left = NULL;
newNode->right = NULL;
return newNode; //Returns the new node
}
void insertSorted(BSTree* tree, int data)
{
//Creates a new temp struct
struct treeNode* newNode = createNode(data);
struct treeNode* tempTree = (*tree);
//If the tree is empty then the data will be at the root
if (tempTree == NULL) {
(*tree) = newNode;
}
//If the tree is not empty the function will call the help function in order to find the right node.
else {
goLeftAndRight(newNode, tempTree, data);
}
}
void goLeftAndRight(struct treeNode* newNode, struct treeNode* tempTree, const int data) {
if (data < tempTree->data && tempTree->left == NULL) {
tempTree->left = newNode;
return;
}
else if (data > tempTree->data && tempTree->right == NULL) {
tempTree->right = newNode;
return;
}
if (data < tempTree->data && data != tempTree->data) {
goLeftAndRight(newNode, tempTree->left, data);
}
else if (data > tempTree->data && data != tempTree->data) {
goLeftAndRight(newNode, tempTree->right, data);
}
}
int counter(int i, const BSTree tree) {
if (tree->left != NULL)
i = 1 + counter(i, tree->left);
if (tree->right != NULL)
i = 1 + counter(i, tree->right);
return i;
}
void balanceTree(BSTree* tree) {
int* sortedArray = writeSortedToArray((*tree));
}
//Code blocks writeSortedToArray ans SorterToArray are the ones causing the problems.
static int* writeSortedToArray(const BSTree tree)
{
struct treeNode* temp = tree;
int i = 0, number = 1 + counter(i, tree);
int* pArray = calloc(number, sizeof(int*));
assert(pArray != NULL);
sorterToArray(temp, pArray, i);
return pArray;
}
//Function where the problem is most likely located.
void sorterToArray(struct treeNode* temp, int* pArray, int i) {
if (temp->left != NULL)
sorterToArray(temp->left, pArray, i);
pArray[i] = temp->data;
i = i + 1;
if (temp->right != NULL)
sorterToArray(temp->right, pArray, i);
}
The problem is indeed in the function you point to. The variable i is local to the function's execution context, and each recursive execution has thus its "own" i. The i = i + 1 only affects one local instance, while other versions of i don't change. That means that none of those i variables will ever get the value 2 or more.
Otherwise put: i is passed by value to the recursive function call.
The solution is to have the function return the updated value of i to the caller:
int sorterToArray(struct treeNode* temp, int* pArray, int i) {
if (temp->left != NULL)
i = sorterToArray(temp->left, pArray, i);
pArray[i] = temp->data;
i = i + 1;
if (temp->right != NULL)
i = sorterToArray(temp->right, pArray, i);
return i;
}
I'm quite new to C and am still coming to grips with a lot of the syntax and idiosyncrasies. I'm not exactly sure what needs changing in order to make my code work but am open to any ideas. I understand that I need to utilize pointers in order to make this work but I am still lost on the specific implementation. I keep getting an error that my myList function is undeclared but I feel like I have declared it already. Is there something I am missing about how C works? Any help would be appreciated
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node* head;
struct node* next;
}node;
node*linkedList ();
int main ()
{
struct linkedList* myList = (struct createList*)malloc(sizeof(struct node));
myList.addNode(5);
myList.addNode(10);
myList.addNode(13);
printf("%d\n", myList.search(10));
printf("The linked list is this big: %d\n", myList.getSize);
}
node* linkedList ()
{
node* head;
node* current;
node*next;
addNode (int x)
{
node keephead = head;
current = head;
while (current.next = NULL)
{
if (current.next = NULL)
{
current.next = node* newnode
newnode.data = x;
newnode.next = NULL;
newnode.head = keephead
}
if (head = NULL)
{
head = current;
}
}
}
int getSize ()
{
int counter = 0;
node countNodes = head;
while (countNodes.next != NULL)
{
countNodes = countNodes.next;
counter++;
}
return counter;
}
int search(int value)
{
int index = 0;
node searchNode = head;
while(searchNode.next!= NULL)
{
searchNode = searchNode.next;
index++;
if (node.value = data)
{
break;
}
else {
index = -1;
}
}
return index;
}
}
I will be simplifying the explanations, so the terms that I will use might not be the correct one.
Proper and consistent indentation would always make your code easier to read and to fix. There were missing semi-colons too, you should watch out for that.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node* head;
struct node* next;
} node;
node* linkedList();
int main()
{
struct linkedList* myList = (struct createList*) malloc(sizeof(struct node));
myList.addNode(5);
myList.addNode(10);
myList.addNode(13);
printf("%d\n", myList.search(10));
printf("The linked list is this big: %d\n", myList.getSize);
}
node* linkedList()
{
node* head;
node* current;
node* next;
addNode (int x)
{
node keephead = head;
current = head;
while (current.next = NULL)
{
if (current.next = NULL)
{
current.next = node* newnode;
newnode.data = x;
newnode.next = NULL;
newnode.head = keephead;
}
if (head = NULL)
{
head = current;
}
}
}
int getSize ()
{
int counter = 0;
node countNodes = head;
while (countNodes.next != NULL)
{
countNodes = countNodes.next;
counter++;
}
return counter;
}
int search (int value)
{
int index = 0;
node searchNode = head;
while (searchNode.next != NULL)
{
searchNode = searchNode.next;
index++;
if(node.value = data)
{
break;
}
else
{
index = -1;
}
}
return index;
}
}
In main(), you should add the return 0; at the end of the function as it is an undefined behavior (AKA not a good thing to do). You could also change it to void main(), but it doesn't compile in clang.
printf("%d\n", myList.search(10));
printf("The linked list is this big: %d\n", myList.getSize);
return 0;
}
You can't put a function within a function in C (nested functions). Put addNode(), getSize(), and search() outside the linkedList() function.
node* linkedList()
{
node* head;
node* current;
node* next;
}
addNode (int x)
{
node keephead = head;
...
}
int getSize ()
{
int counter = 0;
...
return counter;
}
int search (int value)
{
int index = 0;
...
return index;
}
linkedList() does literally nothing now and should be removed.
struct node* next;
} node;
int main()
{
struct linkedList* myList = (struct createList*) malloc(sizeof(struct node));
...
printf("The linked list is this big: %d\n", myList.getSize);
return 0;
}
void addNode (int x)
{
node keephead = head;
In main(), myList is the head of the currently empty linked-list, so it should be initialized to NULL. There's no linkedList data type, only node. Change it to:
node* myList = NULL;
You seem to be applying addNode(), getSize(), and search() to a variable, but C doesn't have that feature (C++ have it though). Add the linked-list head as an argument instead. addNode() needs the & address operator since it will be changing where the head starts.
addNode(&myList, 5);
addNode(&myList, 10);
addNode(&myList, 13);
printf("%d\n", search(myList, 10));
printf("The linked list is this big: %d\n", getSize(myList));
Update the function parameters of addNode(). In the while condition current.next = NULL and if statements, you were using an assignment operator instead of a comparison operator != or ==. You used the variables current and newnode, but never declared it anywhere in the function. There were lots of logic errors here. Change it to:
void addNode (node** head, int x)
{
node* current = *head;
node* newnode = malloc(sizeof(node));
newnode->data = x;
newnode->head = *head;
newnode->next = NULL;
if (*head == NULL)
*head = newnode;
else
{
while (current->next != NULL)
current = current->next;
//current is now the last node of linked list
current->next = newnode;
}
}
Do the same for the function parameters of getSize() and search(). Use node * instead for countNodes and searchNode. -> is the operator for accessing the members of a struct pointer. if statement should be put before it goes to the next node, as it would always skip the first node if left as it is. index should be put before the if statement so the index would update before it breaks out of the loop.
int getSize (node* head)
{
int counter = 0;
node* countNodes = head;
while (countNodes != NULL)
{
countNodes = countNodes->next;
counter++;
}
return counter;
}
int search (node* head, int value)
{
int index = 0;
node* searchNode = head;
while (searchNode != NULL)
{
index++;
if(searchNode->data == value)
break;
searchNode = searchNode->next;
}
if(searchNode->data != value)
index = -1;
return index;
}
Add the function prototypes before main().
void addNode (node** head, int x);
int getSize (node* head);
int search (node* head, int value);
int main()
{
node* myList = NULL;
Everything should work properly now.
For homework I was given this code with the directive to implement a recursive function that calls itself on the next node in the list in main unless the current node is NULL or the value of the current node is equal to 'target'
My recent attempt is the fenced part of the code below. I can get it to print 0, but that's not the whole list. I'm not sure what I'm doing wrong as I've not had much experience with linked lists and nodes.
typedef struct node {
struct node* next;
unsigned short index;
char* value;
} node;
node* create_node(unsigned short index, char* value) {
node* n = malloc(sizeof(node));
n->value = value;
n->index = index;
n->next = NULL;
return n;
}
node* create_nodes(char* values[], unsigned short index, unsigned short num_values) {
if(num_values == 0) {
return NULL;
}
node* n = create_node(index, values[0]);
n->next = create_nodes(values + 1, index + 1, num_values - 1);
return n;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
node* find_match(node* cur, char* target) {
if(cur == NULL){
return NULL;
}
if(cur->value != NULL){
node* result = create_node(cur->index, cur->value);
result->next = find_match(cur->next, cur->value);
}else{
return find_match(cur->next, cur->value);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int main() {
char* values[] = {
"foo", // 0
"bar", // 1
"baz", // 2
"duh", // 3
"dunk", // 4
"derp" // 5
};
node* head = create_nodes(values, 0, 6);
node* target = find_match(head, "dunk");
printf("%d\n", target->index);
return 0;
}
No error messages were given, except a prior segmentation fault I've already 'fixed' but I think it's supposed to print the whole list.
You can insert a single element at a time and send the each element using loop because you know the size of array.Then you have to little change in your code.
struct linkList {
int data;
linkList* next;
}node;
node create(int val){
node tmp;
tmp = (node)malloc(sizeof(struct linkList));
tmp->data = val;
return tmp;
}
node* insertNodeAtHead(linkList* llist,int data) {
node tmp;
tmp = create(data);
tmp->next = llist;
return tmp;
}
Then you can search with your Key just like printing the all element in the List
void print(linkList* head) {
while(head !=NULL){
printf("%d\n",head->data); // check here is this your key or Not
head = head->next;
}
}
But this question is known and before posting any question make sure you try and Search enough in Google !!. Hope you get the idea and implement it in your own way.
There are a few issues in the code.
The problem is in the findmatch function. In this as per the problem statement, the target node should be returned if it is present, else NULL should be returned. This can be achieved as below.
node* find_match(node* cur, char* target) {
if(cur == NULL){
return NULL;
}
if(strcmp(cur->value,target) ==0){
return (cur);
}else if (cur->value != NULL){
return find_match(cur->next, target);
}
else {
return NULL;
}
}
Additional points
In the create_node function you are directly copying the string pointer. This may work in this specific case, but you should ideally allocate memory for the value field separately.
node* create_node(unsigned short index, char* value) {
node* n = malloc(sizeof(node));
n->value = strdup(value);
n->index = index;
n->next = NULL;
return n;
}
While printing the value, you should check if the returned value from findmatch is NULL
node* target = find_match(head, "dunk");
if (target != NULL) {
printf("%d\n", target->index);
}
else {
printf (" Not found\n");
}
I am getting a segmentation fault when trying to print the nodes in my binary tree. It looks to be an issue with the third node. I have searched google and stack overflow for hours but I can not understand what the problem is. I am trying to teach myself data structures in C and am very much a novice so I may be doing something in a frowned upon way.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *left;
struct node *right;
} Node;
typedef struct
{
Node *root;
} BinarySearchTree;
void printInOrder(Node *);
void addNode(Node *, Node *);
int main (void)
{
BinarySearchTree tree;
BinarySearchTree *tree_ptr = &tree;
Node n1, n2, n3;
n1.data = 1;
n2.data = 2;
n3.data = 3;
Node *n1_ptr = &n1;
Node *n2_ptr = &n2;
Node *n3_ptr = &n3;
tree_ptr->root = n1_ptr;
addNode(tree_ptr->root, n2_ptr);
addNode(tree_ptr->root, n3_ptr);
printInOrder(tree_ptr->root);
}
void printInOrder(Node *root)
{
if (root == NULL)
{
return;
} else
{
printInOrder(root->left);
printf("%i\n", root->data);
printInOrder(root->right);
}
}
void addNode(Node *root, Node *node)
{
if (node->data < root->data)
{
if (root->left == NULL)
{
root->left = node;
} else
{
addNode(root->left, node);
}
}
else if (node->data > root->data)
{
if (root->right == NULL)
{
root->right = node;
} else
{
addNode(root->right, node);
}
}
}
output:
1
2
Segmentation fault: 11
There doesn't seem to be an issue with any but the third node. If I comment out the line that adds the second node I get the same error (with only 1 being printed, obviously).
Your initialization is incomplete
n1.data = 1;
n2.data = 2;
n3.data = 3;
should also set the pointers
n1.data = 1;
n1.left = NULL;
n1.right = NULL;
n2.data = 2;
n2.left = NULL;
n2.right = NULL;
n3.data = 3;
n3.left = NULL;
n3.right = NULL;
Problem is occurring because you are not initializing all the member of structure Node type variable.
I would suggest, you should write a function to initialize the Node type variable, like this:
void init_node(Node * nodeptr, int data)
{
nodeptr->data = data;
nodeptr->left = NULL;
nodeptr->right = NULL;
}
and in your main() (or from where ever you want to initialize) you can simply do:
init_node(&n1, 1);
init_node(&n2, 2);
init_node(&n3, 3);
With this, you will never miss assigning NULL to left and right pointer during initialization of Node type variable and chances of the error occurring because of it will be reduced to a greater extent.
I'm creating a binary tree in C in which I use indexes as in a binary search tree. I'm having trouble with a function that finds a node.
My code for the tree is in a separate file and it's the following:
struct node {
struct node *left;
struct node *right;
int index;
void *data;
};
struct node * init_mt()
{
struct node *root = malloc(sizeof(struct node));
root->index = -1;
root->data = NULL;
root->left = root->right = NULL;
return root;
}
void create_mt(struct node *mt, int h, int i)
{
if (h == 0) // end of tree reached
{
mt->index = 0;
mt->left = mt->right = NULL;
return;
}
else
{
mt->index = i;
int l = i-pow(2,h-1);
int r = i+pow(2,h-1);
mt->left = malloc(sizeof(struct node));
mt->right = malloc(sizeof(struct node));
create_mt(mt->left,h-1,l);
create_mt(mt->right,h-1,r);
}
}
struct node * get_node_mt(struct node *mt, int p, int h)
{
if (h == -1) // end of tree reached
{
return NULL;
}
else
{
if (mt->index == p)
{
printf("Found %p\n", mt);
return mt;
}
else if (mt->index > p)
{
get_node_mt(mt->left,p,h-1);
}
else
{
get_node_mt(mt->right,p,h-1);
}
}
}
When I run my main like this (root->left->left is the node index #2):
struct node *root = NULL;
root = init_mt();
create_mt(root,3,8); // root index == 8
printf("%d %p\n", root->left->left->index,root->left->left);
struct node *find;
find = get_node_mt(root,2,3);
printf("%p\n", find);
I get the following output:
2 0x7ffd1dd011a0
Found 0x7ffd1dd011a0
0x0
I don't understand why I get the right pointer both when priting directly using root->left->left and inside the function get_node_mt() but not when I print the pointer I've returned. What am I doing wrong?
The get_node_mt() function calls itself in two places. Neither of these two places return a value.
struct node * get_node_mt(struct node *mt, int p, int h)
{
if (h == -1) // end of tree reached
return NULL;
else if (mt->index == p)
return mt;
else if (mt->index > p)
get_node_mt(mt->left,p,h-1);
else
get_node_mt(mt->right,p,h-1);
}
I reformatted the code a bit and removed a lot of braces. The compiler should've warned about this problem, IMHO.