User defined Functions and Linked Lists in C - c

I'm a bit stuck on how to make a user defined function that would printout the output. I also have to make a user defined function that will add up the data in each node and print out the total but it's not adding up correctly and the format is a little off as well.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
char printout();
int sum();
typedef struct node
{
int number;
struct node*next;
} node;
char printout()
{
};
int sum()
{
int s,sum_all=0, node_sum=0;
for(s=0;s=100;s++)
{
sum_all=node_sum+s;
return printf("The sum of all nodes is %d.\n",sum_all);
};
};
int main()
{
srand (time(NULL));
int i, total=0;
struct node*head=malloc(sizeof(struct node));
head->number = rand()%100;
printf("Node #%d contains %d.\n", 0, head->number);
struct node*here=head;
for (i=1; i<100; i++)
{
here->next=malloc(sizeof(struct node));
here->number=rand()%100;
printf("Node #%d contains %d.\n", i, here->number);
};
total=sum(here->number);
printf("%2.2d", total);
return 0;
}

There is the litany of errors here, but let's just focus on the most important meat:
You should be pass the list's head to the function sum(), ie
sum(head); // This is how you call most linked list functions.
by which you should change the header to
int sum(struct node *head)
{ ... }
This is not an array. You should traverse the linked list correctly.
I can't show all the code for you, as this is what your professor wants you to learn.
But you should be using these
for( struct node*p = head; p!=NULL; p=p->next)
instead of these
for( s=0; s<=100; s++)
You also forgot to step forward in your malloc-and-fill-with-rand loop
here = here->next; // this does in linked lists what i++ does in arrays
and this
sum_all += p->number; // p->number is analogous to array[i]
instead of
sum_all = node_sum +s; // what are s and node_sum anyway?
Also, if you insist that sum return something,
It should return, well, the sum;
return sum_all;
And don't print it inside the function
printf("The sum of all nodes is %d.\n",sum_all); // please don't
Because you're already printing it outside.
total = sum(head);
printf("%2.2d", total);
Please try to think first what your code is going to accomplish instead of putting code blankly.
It will help you a lot. Good luck!

Related

Implementation of BFS using queue and adjacency list in C

I was solving a problem which allowed two types of operations: subtracting one from a number or multiplying it by two, with the source and the destination numbers provided. Input constraints are 1<=n<=10^4 for both numbers. I'm supposed to output the number of operations needed to produce the desired number from the given one. The following is my implementation, getting runtime error and, obviously, I do not know why. It'll be awesome if someone explains the bug. Thanks.
#include <stdio.h>
#include <stdlib.h>
int g[22222][3], v[2222], size;//g == graph, v == visited and size == the size of queue
typedef struct _queue
{
int val;
struct _queue *next;
struct _queue *prev;
} queue;
queue *head=NULL, *last=NULL;
void push(int val)
{
queue *ptr=(queue *) malloc(sizeof(queue));
ptr->next=NULL;
ptr->val=val;
if (head)
{
last->next=ptr;
ptr->prev=last;
}
else
{
head=ptr;
ptr->prev=NULL;
}
last=ptr;
}
void pop()
{
if (size)
{
queue *ptr=last;
last=last->prev;
if (head) last->next=NULL;
free(ptr);
}
}
int front() {return last->val;}
int bfs(int s, int d)//s == source and d == destination
{
int cnt=0;
push(s);
size++;
v[s]=1;
while (size)
{
int u=front();
pop();
size--;
for (int j=1; j<=2; j++)
{
if (d==g[u][j]) return (cnt+1);
if (!v[g[u][j]])
{
v[g[u][j]]=1;
size++;
push(g[u][j]);
}
}
cnt++;
}
}
int main()
{
int n, m, val;
scanf("%d%d", &n, &m);
if (n==m) {printf("0"); return 0;}
val=(n>m?n:m)*2;
v[0]=1;
for (int i=1; i<=val; i++)
{
g[i][1]=2*i;
g[i][2]=i-1;
}
printf("%d", bfs(n, m));
return 0;
}
You have implemented a stack i.e. LIFO (last in first out): you are adding to the end and retrieving from the end.
You should implement a queue i.e. FIFO (first in first out), so if you add to end, you should retrieve from front:
void pop()
{
if (size)
{
queue *ptr=head;
head=head->next;
if (head) head->prev=NULL;
free(ptr);
}
}
int front()
{
return head->val;
}
Also, I guess your aim is to count the smallest number of operations required to produce the desired number from a given one. Your cnt variable does not represent the smallest number of operations, it represents the number of times you retrieved an element from the queue. You need to increment it for each new level instead.
Finally, your bfs should return a value even if there is no path from s to d, so you should put return 0; after the while(size){} loop.
UPD. You need to skip g[u][j] if it is larger than 2 * (10^4) inside of bfs, otherwise those values be enqueued which is a waste of space. By the way your v array has only 2222 elements, it should have at least 20001 (v[20000] is the last one)

Assign a variable to the next item in a linked list

I am having trouble assigning a user entered variable to the "next" variable in a linked list. (ie head->next->num = sum) Normally enclosing the node in parenthesis works to assign a variable to one of the items in the list but i can't seem to apply the same logic to the next item in the list. I'm unsure if it's a syntax issue or allocation but it keeps seg faulting. Code example below of what i'm talking about.
#include <stdio.h>
#include <stdlib.h>
typedef struct fib {
long long num;
struct fib *next;
} fib;
typedef void (*callback)(fib *point);
char menu();
void welcome();
void help();
void exitmssg();
void print(fib *head, callback f);
void display(fib *n);
fib *run(fib *head, int count);
void main() {
long long num1, num2, sum;
int count;
callback disp = display;
fib *head, *pointer, *append;
welcome();
head = malloc(sizeof(fib));
pointer = malloc(sizeof(fib));
printf("Please enter two starting fibonacci numbers:\n");
scanf("%lli", &num1);
scanf("%lli", &num2);
(head->num) = num1;
(head->next->num) = num2;
//((head->next)->num) doesn't work either
Any help is greatly appreciated.
You are trying to use an uninitialized pointer. head->next is not initialized.
head = malloc(sizeof(fib));
pointer = malloc(sizeof(fib));
head->num = num1;
head->next = pointer; // Now next points to something
head->next->num = num2;
pointer->next = NULL; // This needs initialization too
And it's not a syntax error - it's a runtime error. If it was a syntax error, the compiler would tell you and it wouldn't compile/run.
DEMO

Returning a list of numbers from a function in C using Struct

I'm trying to solve this codewars kata
Basically I need to wite a programe that spits out an array/list of numbers from a perticular range (of numbers) which have k primes multiplicatively.
countKprimes(5, 500, 600) --> [500, 520, 552, 567, 588, 592, 594]
Now my program "works" as in it can print the results correctly, but if I put it in codewars' answer area (without main of course), it just runs forever.
"Error code SIGKILL : Process was terminated. It took longer than 12000ms to complete"
This is the codewars template
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// In the preloaded section are some functions that can help.
// They can be used as a small library.
// There is no file to include, only the templates below.
struct node {
int data;
struct node *next;
};
struct list {
size_t sz;
struct node *head;
};
struct list* createList();
// push data at the head of the list
void insertFirst(struct list* l, int data);
struct list* reverse(struct list* l);
void listFree(struct list* l);
// functions to write
struct list* kPrimes(int k, int start, int nd)
{
// your code
}
And this is my code
#include <stdio.h>
struct list{
int a[600];
};
int smallestPrimeFactor(int number){
int x;
for(x = 2; x < number; x++) {
if(number % x == 0) {
return x;
}
}
return number;
}
int primefactors(int ofnumber){
static int counter = 0;
int tempcounter = counter;
int nextnumber = ofnumber/smallestPrimeFactor(ofnumber);
if(nextnumber != 1) {
if(ofnumber >= nextnumber) {
counter++;
primefactors(nextnumber);
}
}
return (counter - tempcounter) + 1;
}
struct list kPrimes(int k, int start, int nd){
int x, g = 0;
struct list ls;
for(x = start; x < nd; x++){
if(primefactors(x) == k){
ls.a[g] = x;
g++;
}
}
return ls;
}
int main(int argc, int **argv){
int p = 5, s = 500, e = 600;
int j = 0;
while(kPrimes(p, s, e).a[j] != '\0'){
printf("%d\n", kPrimes(p, s, e).a[j]);
j++;
}
}
I think the culprit here is
struct list{
int a[600];
};
Maybe while reading the array, the test file is overshooting a's index past '\0'.
I thought of a way of solving that by making a a pointer to integer but doing int *a; prints out nothing.
I know there are more than one way of returning an array. Using referance, using a static array, passing an array as argument, etc. But I want to solve this codewars' way. Think it'll be a nice learning experience.
So, how should I be using
struct node {
int data;
struct node *next;
};
struct list {
size_t sz;
struct node *head;
};
to solve the problem?
You should not bother about the structure themselves, you should simply use the provided functions:
struct list* kPrimes(int k, int start, int nd){
int x, g = 0;
struct list *ls = createList(); // 1. Create the list.
// 2. Maybe check if ls != NULL...
for(x = start; x < nd; x++){
if(primefactors(x) == k){
insertFirst(ls, x); // 3. Insert at the beginning.
g++;
}
}
struct list *rls = reverse(ls); // 4. Reverse the list.
listFree(ls); // 5. Free the original list.
return rls; // 6. Return the reversed list.
}
Since the functions reverse is not documented, I can only guess that it creates a new list without modifying the old one, which is why you need to free it after.
The createList(), insertFirst(), reverse(), and listFree() functions, as well as the function that consumes the return value of your function are all provided to you, and they all work with the types struct list and struct node. How, then, do you imagine it could work if you try to use a differently-defined struct list than those existing functions use?
So yes, you should be using the struct node and struct list types provided to you -- and the handy functions for manipulating them -- rather than defining different structure types with the same tags.

Program that reads numbers from an array and then insert them into list doesn't work

I had to write a program which reads int numbers from an array, and then inserts them one by one if they are bigger than the limit number. What I wrote was:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
struct number_list{
int high_number;
struct number_list *next;
};
typedef struct number_list number_list;
void insert_in_list(int *array, int lim);
int main(void){
int number_seq[SIZE]={1, 2, 3, 4, 5, 6, 7, 8, 9};
int limit;
scanf("%d\n", limit);
insert_in_list(number_seq, limit);
}
void insert_in_list(int *array, int lim){
int i;
number_list *start_node;
for(i=0; i<SIZE; i++){
if(array[i]>lim){
start_node=malloc(sizeof(number_list));
start_node->high_number=array[i];
printf("%d\n", start_node->high_number);
start_node->next=start_node;
}
}
}
What happens is that the program doesn't have any compilation errors (except for a warning that %d expects argument of type *int instead of int, which I also didn't understand, so if anyone could help me with that too would be very kind) but when running, after inserting the limit number, displays a segmentation error (core dump created).
I suppose the problem is in the insert_in_list function, but I don't understand what it is.
There are a couple of things that go wrong here:
(a) The insert_in_list function needs an additional parameter that tells into which list to insert.
(b) Why did you name the member of the number_list structure "high_number". Shouldn't it contain just a number and hence simply be called "number"?
(c) You always set the next pointer to the structure itself. If you want to form a list, it should point to the next node.
(d) in main you need to define a pointer to the first node of your list, which should contain null as long as the list is empty. This "anchor" is what represents your list.
(e) As a hint: Pass a pointer to that anchor to your insert function, because, once the insert function creates the first node it has to deposit the address of that first node into the anchor. Hence your insert function should look like this:
void insert_in_list (number_list** pAnchor, int number)
(f) It is no good idea to define the size of your input array as SIZE and use that symbol in your insert_in_list function. Instead, either path the array and its length as two parameter to the function, or -- as I did in the code line above -- pass just one number per call to the insert function and call it for every number you want to insert.
This will solve your problem however I do not understand why inset_in_list returns nothing and you're not using the list in the main function whatsoever
If thats not intensional either have it return a pointer to the list or create the list in the main and pass a pointer of the list to the function insert_in_list
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
typedef struct node *node_pointer;
typedef struct node{
int high_number;
node_pointer next;
}number_list;
void insert_in_list(int *array, int lim);
int main(void){
int number_seq[SIZE]={1, 2, 3, 4, 5, 6, 7, 8, 9};
int limit;
scanf("%d", &limit);
insert_in_list(number_seq, limit);
}
void insert_in_list(int *array, int lim){
extern void print_list(node_pointer list);
int i;
node_pointer list = NULL;
for(i=0; i<10; i++){
if(array[i]>lim){
node_pointer newnode, last = list;
newnode = (node_pointer)malloc(sizeof(number_list));
newnode->high_number = array[i];
newnode->next = NULL;
if (last == NULL){
list = newnode;
}//first node
else{
while (1) {
if (last->next == NULL) {
last->next = newnode;
break;
}
last = last->next;
}
}
}
}
print_list(list);
}
void print_list(node_pointer list) {
node_pointer which;
which = list;
printf("\nList 4 :");
if (which == NULL){ printf("Empty\n"); }
while (which != NULL) {
printf("%d", which->high_number);
which = which->next;
}
}

Sorting of double linked list in C

I created a program to sort double linked list in ascending order, and the result was unexpected, but when I used the same program for descending order by changing a line in it, it worked perfectly. Please tell where m going wrong
/*Structure of double linked list */
struct dlink
{
int num;
struct dlink *plink; //previous address
struct dlink *nlink; //next address
};
void main()
{
clrscr();
struct dlink *st;
st=NULL;
append(&st,100); //to put values in double linked list
append(&st,32);
append(&st,200);
append(&st,107);
display(st);
ascending(&st);
display(st);
getch();
}
/* function to add values to double linked list */
void append(struct dlink **q,int n)
{
struct dlink *temp,*r;
temp=*q;
if(temp==NULL)
{
temp=(dlink *)malloc(sizeof(dlink));
temp->num=n;
temp->plink=NULL;
temp->nlink=NULL;
*q=temp;
}
else
{
while(temp->nlink!=NULL)
temp=temp->nlink;
r=(dlink *)malloc(sizeof(dlink));
r->num=n;
r->nlink=NULL;
r->plink=temp;
temp->nlink=r;
}
}
void ascending(struct dlink **q)
{
struct dlink *temp,*s,*p=NULL;
temp=*q;
int a=count(*q);
printf(" a %d ",a);
for(int i=0;i<a;i++,temp=temp->nlink)
{
s=temp->nlink;
for(int j=i+1;j<=a;j++,s=s->nlink)
{
if((temp->num) < (s->num)) //for ascending i was using //if(temp->num > s->num but it is not getting desired result it is just printing //one value and by this one for descending order program is working perfectly //for descending order
{
(s->plink)->nlink=s->nlink;
if(s->nlink!=NULL)
(s->nlink)->plink=s->plink;
s->plink=temp->plink;
s->nlink=temp;
temp=s;
(temp->nlink)->plink=temp;
}
}
if(i==0)
*q=temp;
if(i!=0)
{
p->nlink=temp;
temp->plink=p;
}
p=temp;
}
temp=*q;
/* To see if the addresse , previous address , next address are correct */
while(temp!=NULL)
{
printf("as %u %u %u\n",temp->plink,temp->nlink,temp);
temp=temp->nlink;
}
}
Look at this part
int a=count(*q);
for(int i=0; i<a; i++,temp=temp->nlink)
{
s=temp->nlink;
for(int j=i+1; j<=a; j++,s=s->nlink)
{ ....
Seems you are using indexes from 0 (first loop) to count(*q) (second) for a list with count(*g) elements.
Something is probably wrong in your algorithm - even if it doesnt cause "index out of bounds" errors (because you don't use arrays).
And it appears when you try to sort the second way, because you have not tested the first way seriously enough.

Resources