C sum of Squares from linked list - c

Hello im trying to make a program that takes a linked list of integers and sums the squares of the int, using recursion. I have tried this so far, however i cant get the function of summin the squares to work. I dont know if using the pow() is the best way?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include<math.h>
typedef struct node
{
int value;
struct node* next;
} node;
/* terminal node at the end of the list */
node SENTINEL = {0, 0};
/* utility functions to create and free lists */
node * make_node(int v, node * q)
{
node* p = (node*) malloc(sizeof(node));
p->value = v;
p->next = q;
return p;
}
int sum_squares(node* list)
{
if(list == 0)
return 0;
else
{
return(pow(&list, 2) + sum_squares(list));
}
}
void free_node(node* p)
{
if(p == &SENTINEL)
return;
else
{
free_node(p->next);
free(p);
}
}
int main(void)
{
int sum;
node* list =
make_node(1,
make_node(2,
make_node(3,
make_node(4,
make_node(5, &SENTINEL)
)
)
)
);
sum = sum_squares(list);
printf("The sum of squares is: %d\n",sum);
free_node(list);
return 0;
}
it should equal 55 with the current numbers

There are a few things that you should edit!
In your sum_squares function, your base case checks whether current node list is equal to 0, but you should check whether it's the sentinel node.
In the recursive case, you should use pow(&list, 2). &list, however, returns the address of the argument list. What you're looking for is the integer value held in the node struct, which you get by using the -> operator. &list becomes list->value.
Finally, when you recursively call your next function, you pass it the same node. This will cause it to infinitely call itself on the same node, and never actually step through the list. Instead of just passing list again, you should pass list->next!
The changes are applied below:
int sum_squares(node* list)
{
if (list == &SENTINEL)
return 0;
return (pow(list->value, 2) + sum_squares(list->next));
}

Related

How to use double pointers in binary search tree data structure in C?

I'm working on implementing a binary search tree data structure in C, but I got stuck at the part where you point to the left or right child. I understand that if the value you're inserting is smaller than the root, it goes to the left and to the right if it's larger. I'm just struggling with the double pointers part as shown in the code below. Let's take bs_tree_insert_left for example, I want pos->left_child to point to the left_child in order to place the value given there, but I'm not sure how I would write this.
For context regarding the main function, the numbers in arr[] will be randomly shuffled but I removed that part of the code to keep the post short and compact.
struct node
{
int value;
struct node *left_child;
struct node *right_child;
};
typedef struct node BSTree;
typedef struct node* BSTreePos;
BSTree *bs_tree_make(int value){
// Allocate memory for new node
struct node* origin = (struct node*)malloc(sizeof(struct node));
// Assign data to this node
origin->value = value;
// Initialize left and
// right children as NULL
origin->left_child = NULL;
origin->right_child = NULL;
return (origin);
}
BSTreePos bs_tree_insert_left(int value, BSTreePos pos){
pos->left_child = bs_tree_make(value);
return pos->left_child;
}
void insert_value(int value, BSTreePos pos)
{
if (pos == NULL) return bs_tree_make(value);
if (value < pos->value)
{
pos->left_child = bs_tree_insert_left(value, pos->left_child);
}
else if (value > pos->value)
{
pos->right_child = bs_tree_insert_right(value, pos->right_child);
}
}
int main(void)
{
// Create an array with the values 1, 2, ..., 10 and print out the content.
int n = 10;
int arr[n];
for (int i = 0 ; i < n ; i++) {
arr[i] = i + 1;
}
print_array(n, arr);
BSTree *tree = bs_tree_make(arr[0]);
for (int i = 1 ; i < n ; i++) {
BSTreePos pos = bs_tree_root(tree);
insert_value(arr[i], pos);
}
return 0;
}
You know what, I'm just going to write the correct algorithm that uses the double pointer to maximum effect.
void insert_value(int value, struct node **node)
{
if (*node == NULL) {
*node = malloc(sizeof(struct node));
node[0]->value = value;
node[0]->left_child = NULL;
node[0]->right_child = NULL;
} else if (node[0]->value < value)
insert_value(value, &node[0]->left_child);
else if (node[0]-> value > value)
insert_value(value, &node[0]->right_child);
/* else duplicate value found -- don't insert (from OP's code) */
}
BSTree *tree = NULL;
for (int i = 0 ; i < n ; i++) {
insert_value(arr[i], &tree);
}
node[0]->value is the idiomatic way of accessing a struct through a double pointer.
But let's look at how this works and how much value this gets out of the double pointer. The empty tree is stored as the NULL pointer. This makes initializing the tree and adding a node to the tree the same code. Notice how insert_value takes a double pointer to the tree; this allows it to fill out the root node when adding the first node, or any child node thereof. Thus double pointer which is pointer to pointer is used to update a pointer to a node when we make a new one.
With this algorithm, having a bs_tree_insert_left literally makes no sense. The whole idea is the code that does the insertion doesn't know where it is inserting the node.
Fun fact: the compiler will transform away the recursion for us when compiling with optimizations.

Putting a linked list in ascending order in C

I am trying to accomplish a function that grows a linked list while also putting them in ascending order at the same time, I have been stuck for a while and gained little progress. I believe my insertLLInOrder is correct it's just the createlinkedList that is messing it up.
Sometimes my output comes out fully and other times it only prints out some of the list.
Anything helps!
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
node *createlinkedList(int num);
node *insertLLInOrder(node * h, node * n);
void display(node * head);
int randomVal(int min, int max);
int
main()
{
int usernum = 0;
node *HEAD = NULL;
printf("How many Nodes do you want? ");
scanf("%d", &usernum);
srand(time(0));
HEAD = createlinkedList(usernum);
display(HEAD);
return 0;
}
node *
createlinkedList(int num)
{
int i;
int n = num;
node *head = NULL;
node *newNode;
node *temp;
for (i = 0; i < n; i++) {
newNode = (node *) malloc(sizeof(node));
newNode->next = NULL;
newNode->data = randomVal(1, 9);
temp = insertLLInOrder(head, newNode);
head = temp;
}
return head;
}
int
randomVal(int min, int max)
{
return min + (rand() % (max - min)) + 1;
}
node *
insertLLInOrder(node * h, node * n)
{
//h is the head pointer, n is the pointer to new node
node *ptr = h;
node *previous = NULL;
while ((ptr != NULL) && (ptr->data < n->data)) {
previous = ptr; // remember previous node
ptr = ptr->next; // check for the next node
}
if (previous == NULL) {
//h is an empty list initially
n->next = NULL;
return n; // return the pointer of the new node
}
else {
//if there are nodes in the linked list
// previous will point to the node that has largest value, but smaller than new node
n->next = previous->next; // insert new node between previous, and previous->next
previous->next = n;
return h; // return old head pointer
}
}
void
display(node * head)
{
node *p = head;
while (p != NULL) {
printf("%d, ", p->data);
p = p->next;
}
}
Obviously in your insertLLInOrder() if the first while loop gives previous == NULL it means that you must insert at list head, which is not what your are doing.
Just change n->next = NULL; to n->next = h; and it should improve behavior.
Taking a step back and perspective
This is a very simple error, but it is made harder to spot because of the way you wrote your code.
The bug in itself is not very interesting, but it can help to get a higher perspective on why it happened and how to avoid such bugs.
And, no, running a debugger is not very helpful for such cases!
Having to run a debugger happens sometimes, but it merely means that you have lost the control of your program. Like having a parachute can be a safety mesure for a pilot, but if he has to use it, it also means that the pilot lost control and his plane is crashing.
Do you know the story of the Three Ninjas Programmers?
The three Ninjas
The chief of ninjas orders three Ninja to show him their training level. There is a Noob, a Beginner and a Senior. He asks them to reach a small cabin, on the other side of a field, take some object inside and come back.
The first Ninja is a noob, he runs and jumps across the field with all his speed but soon enough he walks on a (plaster) mine. He goes back at the start line and confesses his failure, which is obvious because his previously black shirt is now covered by white plaster.
The second Ninja shows some practice. You can tell he failed like the Noob on a previous try and that now he is wary. He is very slow and very careful. He sneaks very slowly across the field watching closely everywhere at each step. He gets quite close to the cabin, and everybody believes he will succeed, but eventually, he is also blown by a mine at the last second. He also goes back disappointed to the starting point, but he somehow believes it will be hard for the third Ninja to do any better.
The third Ninja is a Senior. He walks calmly across the field in a straight line, enter the cabin, and goes back without any visible trouble, still merely walking across the field.
When he gets back to the starting point the other two Ninjas are stunned and ask him eagerly:
- How did you avoid the mines?
- Obviously, I didn't put any mines on my path in the first place; why did you put mines in yours?
Back to the code
So, what could be done differently when writing such a program?
First using random values in code is a bad idea. The consequence is that the code behavior can't be repeated from one run to the next one.
It is also important that the code clearly separate user inputs (data) and code manipulating that data.
In that case, it means that the createLinkedList() function should probably have another signature. Probably something like node *createlinkedList(int num, int data[]) where the data[] array will contains values to sort. It is still possible to fill input data with random values if it is what we want.
That way, we can easily create tests set and unit tests, like in code below:
Home made unit tests suite
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
node *createlinkedList(int num, int * data);
node *insertLLInOrder(node * h, node * n);
/* No need to have a test framework to write unit tests */
/* Check_LL is some helper function comparing a linked list with test data from an array */
int check_LL(node * head, int num, int * data)
{
node *p = head;
int n = 0;
for (; n < num ; n++){
if (!p){return 0;}
if (p->data != data[n]){return 0;}
p = p->next;
}
return p == NULL;
}
void test_single_node()
{
printf("Running Test %s: ", __FUNCTION__);
int input_data[1] = {1};
int expected[1] = {1};
node * HEAD = createlinkedList(1, input_data);
printf("%s\n", check_LL(HEAD, 1, expected)?"PASSED":"FAILED");
}
void test_insert_after()
{
printf("Running Test %s: ", __FUNCTION__);
int input_data[2] = {1, 2};
int expected[2] = {1, 2};
node * HEAD = createlinkedList(2, input_data);
printf("%s\n", check_LL(HEAD, 2, expected)?"PASSED":"FAILED");
}
void test_insert_before()
{
printf("Running Test %s: ", __FUNCTION__);
int input_data[2] = {2, 1};
int expected[2] = {1, 2};
node * HEAD = createlinkedList(2, input_data);
printf("%s\n", check_LL(HEAD, 2, expected)?"PASSED":"FAILED");
}
/* We could leave test code in program and have a --test command line option to call the code */
int
main()
{
test_single_node();
test_insert_after();
test_insert_before();
}
node *
createlinkedList(int num, int * data)
{
int i;
node *head = NULL;
for (i = 0; i < num; i++) {
node * newNode = (node *) malloc(sizeof(node));
newNode->next = NULL;
newNode->data = data[i];
head = insertLLInOrder(head, newNode);
}
return head;
}
node *
insertLLInOrder(node * h, node * n)
{
//h is the head pointer, n is the pointer to new node
node *ptr = h;
node *previous = NULL;
while ((ptr != NULL) && (ptr->data < n->data)) {
previous = ptr; // remember previous node
ptr = ptr->next; // check for the next node
}
if (previous == NULL) {
//h is an empty list initially
n->next = NULL;
return n; // return the pointer of the new node
}
else {
//if there are nodes in the linked list
// previous will point to the node that has largest value, but smaller than new node
n->next = previous->next; // insert new node between previous, and previous->next
previous->next = n;
return h; // return old head pointer
}
}
As you can see the third test spot the bug.
Of course, you could use some available third party Unit Test library, but the most important point is not the test library, but to write the tests.
Another point is that really you should interleave writing tests and writing implementation code.
This typically helps for writing good code and is what people call TDD. But my answer is probably already long enough, so I won't elaborate here on TDD.

Parsing an uninitialized value into a function

I'm trying to write a little program that goes through a list of numbers in an array and just inserts them into a binary search tree. Here's what I have:
#include <stdio.h>
#include <stdlib.h>
typedef struct node_t node_t;
struct node_t {
int data;
node_t *left;
node_t *right;
};
int insert(node_t *node, int n);
int main(void) {
int array[8] = {5, 8, 3, 6, 9, 2, 4, 7};
int i;
node_t *root;
for (i = 0; i < 8; i++) {
insert(root, array[i]);
}
return 0;
}
int insert(node_t *node, int n) {
if (node == NULL) {
node = malloc(sizeof node);
node->data = n;
return 1;
}
if (n > node->data) {
insert(node->left, n);
} else if (n < node->data) {
insert(node->right, n);
} else {
return -1;
}
return 0; // Suppress 'control reaches end of non-void function'
}
when I compile with gcc I get a warning saying "'root' may be used uninitialized in this function". Running it causes on errors (on Windows at least), however, printing out root->data in main() yields a 0.
The idea I was trying to implement was the insert() function checking if the pointer to the input node was NULL so it could then malloc it. Also, due to how the recursion is handled, the number being inserted should be inserted at that node. If the node did NOT equal NULL, then I would recursively call insert() again on the side of the node where the number should be inserted.
I understand the reason why this doesn't work has something to do with the pointer root not being directed anywhere, nor root->left/root->right, however, I don't know what I can do to fix this. Any help would be appreciated, thank you!
There might be more problem with the code you posted but I listed a few problems below.
Since it is the node that you need to allocate memory for if it contains NULL, you need to change this:
if (node->data == NULL) {
To this:
if (node == NULL) {
Also, you need to initiate the root node, since it will just contain whatever happens to be on stack at that moment and it may or may not be NULL (e.i. the thing you want to compare with in insert function). So initiate it like so:
node_t *root = NULL;
Last thing is to change to malloc to calloc function (or do a memset to zero on the memory separately). Otherwise the variables node->left and node->right can contain non NULL values that could result in making use of uninitialized memory.
Your program does indeed pass an unintialized root variable to the insert() function. But even if initialize root you are still going to have problems
because in order to populate the tree, you need to pass pointer to pointer (as you want to be able modify the pointer root in main()). Similarly, you need modify the argument to
the recursive calls to insert() as well.
I notice you don't really use the return value of insert(). So, it can just be a void function. I added some in-code comments to explain some problems.
#include <stdio.h>
#include <stdlib.h>
typedef struct node_t node_t;
struct node_t {
int data;
node_t *left;
node_t *right;
};
void print(node_t *r) { /* In order tree traversal. Gives the sorted output. */
if (!r) return;
print(r->left);
printf("%d ", r->data);
print(r->right);
}
void insert(node_t **node, int n);
int main(void) {
int array[] = {5, 8, 3, 6, 9, 2, 4, 7}; /* Removed the size. It can be calculated using sizeof and helps when array size changes */
int i;
node_t *root = NULL;
/* Without hard-coding, array size can be calculated like this. */
for (i = 0; i < sizeof array/sizeof array[0]; i++) {
insert(&root, array[i]);
}
print(root);
return 0;
}
void insert(node_t **node, int n) {
if (*node == NULL) {
*node = malloc(sizeof *node);
if (*node == NULL) { /* Need to check the return value for failure. */
perror("malloc");
exit(1);
}
(*node)->left = (*node)->right = NULL;
(*node)->data = n;
return;
}
if (n < (*node)->data) /* Insert smaller elements on the left for it to be a binary tree - but not neccessary */
insert(&(*node)->left, n);
else /* Another else below this isn't needed. There can't be any error with the number 'n' itself */
insert(&(*node)->right, n);
}

Address of a node in linked list changes automatically in c

I am learning pointers in c and wrote a program which inserts elements into linked list and prints them in the end.
// this is exercise 2 in chapter 11 on pointers
#include <stdio.h>
#include <stdbool.h>
typedef struct node
{
int value;
struct node * next;
}node;
/**
Insert into linked list
**/
bool insert(node * list, int n);
void printList(node *startNode);
int main(void)
{
node n1,n2;
n1.value = 0;
n2.value = 1;
n1.next = &n2;
n2.next = NULL;
// insert 2 into list
insert(&n1, 2);
// print the updated list
printList(&n1);
printf("Program Executed Successfully \n");
return 0;
}
bool insert(node * list, int n)
{
while(list->next != NULL)
{
if (list->value < n)
{
list = list->next;
}
else
{
node tempNode;
tempNode.value = n;
tempNode.next = list->next;
list->next = &tempNode ;
return true;
}
}
node tempNode;
tempNode.value = n;
tempNode.next = list->next;
list->next = &tempNode ;
return false;
}
void printList(node * startNode)
{
while(startNode->next != NULL)
{
printf("%i\n", startNode->value);
startNode = startNode->next;
}
}
Insertion seems to be fine. I have initially two nodes and then I added one more with a value of 2 but when I print, it just prints the first two elements correctly.
I used GDB debugger and tried to trace where the problem occurs, i saw that when it has printer first and second node, the address of the third node has automatically changed to
0x7ffff7dea560 <_dl_fini>
before at the start of the print function it was
0x7ffffe018
and the output of the complete program is
0
1
-777224576
-443987883
Segmentation fault
The insert function just looks wrong, but the worst offenders are these lines from the function:
else
{
node tempNode;
...
list->next = &tempNode ;
}
Here you declare a local variable `tempNode, and save a pointer to it in the list. The variable will go out of scope and cease to exist once the closing curly brace is reached, leaving you with a stray pointer. Attempting to dereference that stray pointer will lead to undefined behavior.
A little further down you do the same mistake again, saving a pointer to a local variable.

How to dynamically populate Linked List with Fibonacci series

I have a linked list, which I wanted to populate up to a certain loop number. I have my code below is shows a Fibonacci series using a C Linked list.
Here is my code without any loop:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int count;
int fibo;
struct Node* next;
}node;
int
fibo(int val){
if(val == 1 || val == 2) {
return 1;
}
return fibo(val - 1) + fibo(val - 2);
}
int
main (void)
{
node f1, f2, f3;
f1.count = 1;
f1.fibo = fibo(1);
f2.count = 2;
f2.fibo = fibo(2);
f3.count = 3;
f3.fibo = fibo(3);
f1.next = &f2;
f2.next = &f3;
f3.next = NULL;
printf("f1 fibo : %i\n", f1.fibo);
printf("f2 fibo : %i\n", f2.fibo);
printf("f3 fibo : %i\n", f3.fibo);
return (0);
}
Now I want to do this via a loop. How would I do that?
For this answer, I'm going to ignore the computational efficiency concerns that arise from recomputing all of the Fibonacci numbers up to the given number you are retrieving with each call to fibo(n).
Linked lists are not usually "random access" data structures that let you access an arbitrary element with an index. When using a linked list with pointers, you only need to have the pointer to the head (first element) of the linked list. You then traverse the list starting at the head using a loop going through each next link. If a list is empty, your head is usually NULL.
You can apply this here. One way (there are several) is to define a function to allocate and set a single entry:
node *set_fibo(int n)
{
node *fibo_entry = malloc(sizeof(node));
if ( fibo_entry == NULL ) {
// error
}
fibo_entry->count = n;
fibo_entry->fibo = fibo(n);
fibo_entry->next = NULL;
return fibo_entry;
}
And then in your main:
node *fibo_list = NULL;
node *last_fibo = NULL;
// Assume n_fibo is the number of Fibonacci numbers you want to store in order
for ( int n = 1; n <= n_fibo; n++ ) {
if ( n == 1 )
fibo_list = last_fibo = set_fibo(1);
else {
last_fibo->next = set_fibo(n);
last_fibo = last_fibo->next;
}
}
Although the question has already been answered, I would like to add something regarding the efficiency aspect of your code. As pointed out before, you do not have to calculate the fibo value by starting from the beginning, since you saved the latest results in the singly linked list.
So given you have the following list 1-1-2-3-5-, you can easily calculate the fibo value of the new node by simply adding the fibo value of the two lates elements (i.e. 3 and 5). Hence the value of the fibo value of the new node should be 8.
Given the pointer to the second last element, this function will add add a new node to the list and set the correct fibo value:
void addNode(struct Node* node){
struct Node* n = malloc(sizeof(struct Node));
n->next = NULL;
n->count = node->next->count + 1;
n->fibo = node->fibo + node->next->fibo;
node->next->next = n;
}
In order to use this function, you have to create the first two nodes in the list:
struct Node* n2 = malloc(sizeof(struct Node));
n2->count = 2;
n2->fibo = 1;
n2->next = NULL;
struct Node* n1 = malloc(sizeof(struct Node));
n1->count = 1;
n1->fibo = 1;
n1->next = n2;
If you now want to add - lets say 10 - new nodes, you simply do:
struct Node* ptr = n1;
int i;
for(i=0; i<10;i++) {
addNode(ptr);
ptr = ptr->next;
}
If you now want to print the entries of all nodes in the list, simply iterate over the list until you reach NULL.
ptr = n1;
while(ptr != NULL) {
printf("fib(%d) = %d\n ", ptr->count, ptr->fibo);
ptr = ptr->next;
}
Please keep in mind, that you have to manually free dynamically allocated items!
In your example, the nodes are automatic variables in main. They are not dynamically allocated and they live as long as you don't return from main. You can extend this concept with a automatic array of nodes:
#include <stdio.h>
#include <stdlib.h
typedef struct Node Node;
struct Node {
int count;
int fibo;
Node* next;
};
#define N 30
int main (void)
{
Node fibo[N];
Node *head = NULL;
Node **p = &head;
int f1 = 0;
int f2 = 0;
for (size_t i = 0; i < N; i++) {
Node *nd = &fibo[i];
nd->count = i + 1;
nd->fibo = f2 + f1 ? f2 + f1 : 1;
f1 = f2;
f2 = nd->fibo;
*p = nd;
p = &(*p)->next;
}
*p = NULL;
Node *nd = head;
while (nd) {
printf("fib(%d) == %d\n", nd->count, nd->fibo);
nd = nd->next;
}
return (0);
}
It's not clear, though, why you need the Fibonacci series as linked list. Also, a word of warning: Don't mix nodes on the stack (like here) and nodes on the heap (as in lurker's answer) in a list. This answer just extends your answer to many nodes, whereas lurker's answer shows a more general concept of linked lists.
Here is how I think you can do it. You can use an array for the nodes.
node f[3];
int i;
for ( i = 0 ; i < 3 ; i++ )
{
f[i].count = i+1;
f[i].fibo = fibo (i+1);
if ( i == 2 )
{
f[i].next = NULL;
}
else
{
f[i].next = &f[i+1];
}
}

Resources