Getting input into a linked list using a loop - c

I made this program to learn about linked lists as I am just starting out with them. The program terminates immediately after the statement "Enter the amount of pesticide"(it is a school assignment). Also, I am unsure how do I keep the length of the list limited to the size input by the user.
#include<stdio.h>
struct plants{
int val;
struct plants *next;
};
void printlist();
int main(){
struct plants* head = NULL;
struct plants* current= head;
head = malloc(sizeof(struct plants));
int counter,size;
printf("Enter the number of plants\n");
scanf("%d",&size);
printf("Enter the amount of pesticide each plant has.\n");
while(current!=NULL){
scanf("%d",current->val);
current= current->next;
}
return 0;
}

#include<stdio.h>
#include<malloc.h>
int main()
{
int count = 0;
int size = 0;
printf("Enter the number of plants\n");
scanf("%d",&size);
printf("Enter the amount of pesticide each plant has.\n");
You have to allocate the memory for each node inside the while loop. If you like to add the new node at the end of the list notice the end of the list by a pointer to the pointer at the end of the list. Apart form this you have to pass the addres of the value to be read to scanf:
struct plants * head = NULL;
struct plants ** current = &head; // current refers there, where next node has to be placed
while( count < size ) // do it for "size" nodes
{
*current = malloc(sizeof(struct plants)); // allocate memory for the node right to target
scanf( "%d", &((*current)->val)); // read the data
(*current)->next = NULL; // node is last node in list, so its successor is NULL
current = &((*current)->next); // step on forward
count ++; // increment number of nodes
}
Note since the type of current is struct plants ** this codes puts the new node to head for the first element of the list and to (*current)->next for all further nodes of the list.
It would be easier to add the new node at the head of the list:
struct plants * head = NULL; // init head with NULL (this becomes end of the list)
while( count < size ) // do it for "size" nodes
{
struct plants * current = malloc(sizeof(struct plants)); // allocate memory for the node
scanf( "%d", &current->val); // read the data
current->next = head; // successor of node is head
head = current; // new node is head of list
count ++; // increment number of nodes
}
This will print your list:
struct plants *temp = head;
while( temp != NULL )
{
printf( "%d ", temp->val );
temp = temp->next;
}
Don't forget to free the list at the end of your program:
while ( head != NULL )
{
struct plants *next = head->next;
free( head );
head = next;
}
return 0;
}

struct plants* head = malloc(sizeof(struct plants));//declare an initialize in memory
struct plants* current= head;
int i = 0;
struct plants* aux = NULL;
while(i ++ < size)
{
aux = malloc(sizeof(struct plants)); // used for new values
scanf("%d", aux->val);
aux->next = NULL;
current->next = aux;
current = aux;
}
Loop while you have less than the quantity required by user. Use an auxiliar node. Read the value, set the current next position to the aux node, the aux node to null and set the current node to aux to be sure you are at the last node from the list.

Lot of things to be corrected, check for the code below. and should be pretty easy for a beginner to understand. I haven't changed the format of your code for ease of understanding
#include<stdio.h>
#include<stdlib.h>
struct plants{
int val;
struct plants *next;
};
void printlist();
int main(){
int i;
struct plants* head = NULL,*temp=NULL;
struct plants* current= head;
int counter,size;
printf("Enter the number of plants\n");
scanf("%d",&size);
printf("Enter the amount of pesticide each plant has.\n");
for(i=0;i<size;i++){
temp = malloc(sizeof(struct plants));
scanf("%d",&temp->val);
temp->next=NULL;
if(head==NULL)
{
head=temp;
current=head;
}
else
{
current->next=temp;
current=temp;
}
}
current = head;
while(current!=NULL){
printf("%d\t",current->val);
current= current->next;
}
}

Related

Creating an entire doubly linked list in one function

I'm new to DSA and currently learning linked-list. I was trying to create an entire linked list in one function. The first scanf in createList function doesn't seem to assign the input to the address provided(i.e. &n). I tried printing n right after scanf. It doesn't print n to console at all.
As a result, the output is not the way I expected. I can't figure out why.
//ENTIRE CODE HERE
#include<stdio.h>
#include<stdlib.h>
struct node {
struct node* prev;
int data;
struct node* next;
};
void print_nodes(struct node* );
struct node* addToEmpty(struct node*, int);
struct node* addAtEnd(struct node*, int);
struct node* createList(struct node*);
int main() {
struct node* head = NULL;
head = createList(head);
print_nodes(head);
}
void print_nodes(struct node* head) {
struct node* ptr = head;
while (ptr != NULL) {
printf("%d ", ptr->data);
ptr = ptr->next;
}
printf("\n");
}
struct node* addToEmpty(struct node* head, int data) {
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
head = temp;
return head;
}
struct node* addAtEnd(struct node* head, int data) {
struct node* tp = head;
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
while (tp->next != NULL) {
tp = tp->next;
}
tp->next = temp;
temp->prev = tp;
return head;
}
struct node* createList(struct node* head) {
int n, data, i;
printf("Enter the number of nodes: ");
scanf("%d ", &n);
if (n == 0)
return head;
printf("Enter the element of node 1: ");
scanf("%d ", &data);
head = addToEmpty(head, data);
for (i = 1; i < n; i++) {
printf("Enter the element of node %d: ", i + 1);
scanf("%d", &data);
head = addAtEnd(head, data);
}
return head;
}
your problem is so simple , instead of scanf("%d ", &n); , just write scanf("%d", &n); by which I mean to remove the wite space after %d as it's producing some strange behavior in your case , as if you refer to scanf() manual page , they say that :
A sequence of white-space characters (space, tab, newline,
etc.; see isspace(3)). This directive matches any amount
of white space, including none, in the input.
which is supposed to ignore any whitespace after the number entered till getting a valid char.
and here is the full code but with this only small modification:
#include<stdio.h>
#include<stdlib.h>
struct node {
struct node* prev;
int data;
struct node* next;
};
void print_nodes(struct node* );
struct node* addToEmpty(struct node*, int);
struct node* addAtEnd(struct node*, int);
struct node* createList(struct node*);
int main() {
struct node* head = NULL;
head = createList(head);
print_nodes(head);
}
void print_nodes(struct node* head) {
struct node* ptr = head;
while (ptr != NULL) {
printf("%d ", ptr->data);
ptr = ptr->next;
}
printf("\n");
}
struct node* addToEmpty(struct node* head, int data) {
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
head = temp;
return head;
}
struct node* addAtEnd(struct node* head, int data) {
struct node* tp = head;
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
while (tp->next != NULL) {
tp = tp->next;
}
tp->next = temp;
temp->prev = tp;
return head;
}
struct node* createList(struct node* head) {
int n, data, i;
printf("Enter the number of nodes: ");
scanf("%d", &n);
if (n == 0)
return head;
printf("Enter the element of node 1: ");
scanf("%d", &data);
head = addToEmpty(head, data);
for (i = 1; i < n; i++) {
printf("Enter the element of node %d: ", i + 1);
scanf("%d", &data);
head = addAtEnd(head, data);
}
return head;
}
and this is the output:
Enter the number of nodes:3
Enter the element of node 1:1
Enter the element of node 2:2
Enter the element of node 3:3
1 2 3
I tried out your code and found issues with the space in the literal string in the "scanf" statements. I see that someone else found that and offered up the solution to that with the cleanup of the "scanf" statements. I would say that if you are to accept an answer, select the first one. However, I just wanted to also offer up my code snippet with a couple of additional tweaks.
#include<stdio.h>
#include<stdlib.h>
struct node
{
struct node* prev;
int data;
struct node* next;
};
void print_nodes(struct node* );
struct node* addToEmpty(struct node*, int);
void addAtEnd(struct node*, int); /* No requirement for a node to be returned as the pointers are all set up in the function */
struct node* createList(struct node*);
int main()
{
struct node* head = NULL;
head = createList(head);
print_nodes(head);
}
void print_nodes(struct node* head)
{
struct node* ptr = head;
while (ptr != NULL)
{
printf("%d ", ptr->data);
ptr = ptr->next;
}
printf("\n");
}
struct node* addToEmpty(struct node* head, int data)
{
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
//head = temp;
return temp; /* Return the pointer to the new struct - no need for update of head here */
}
void addAtEnd(struct node* head, int data)
{
struct node* tp = head;
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
while (tp->next != NULL)
{
tp = tp->next;
}
tp->next = temp;
temp->prev = tp;
return;
}
struct node* createList(struct node* head)
{
int n, data, i;
printf("Enter the number of nodes: ");
scanf("%d", &n);
if (n == 0)
return head;
printf("Enter the element of node 1: ");
scanf("%d", &data);
head = addToEmpty(head, data);
for (i = 1; i < n; i++)
{
printf("Enter the element of node %d: ", i + 1);
scanf("%d", &data);
addAtEnd(head, data);
}
return head;
}
First off, since there is not a need to return a "struct" pointer in the function "addAtEnd", I revised that to be a "void" function return signature. Second, in the "addToEmpty" function, one can just return the pointer value in "temp" instead of placing the value into the input parameter "head"; however, it works either way. It is just a matter of choice.
As a sample, here is some output data at the terminal.
#Una:~/C_Programs/Console/CompleteList/bin/Release$ ./CompleteList
Enter the number of nodes: 4
Enter the element of node 1: 65535
Enter the element of node 2: 2458
Enter the element of node 3: -44
Enter the element of node 4: 3258779
65535 2458 -44 3258779
I would suggest trying out both iterations.
Other answers have pointed at the specific problem you experienced (bad scanf() parameter string).
Going beyond that, however, there are two other "issues(?)".
First is to "create an entire linked list in one function".
In your code, main() calls only one function, but that function uses two "helper" functions to get the job done.
Every line of code is an opportunity for a bug to lurk unseen.
Re-using code is a way to reduce the chances for bugs to appear.
Secondly, the code appears to be correct, but does not prove that the doubly linked list is anything more than a singly linked list.
Both of these matters are addressed below creating (in one function, and later demonstrating) a circular doubly linked list.
Comments explain changes from the original code to this version.
Finally, an additional function is used here to prevent memory leaks.
#include <stdio.h>
typedef struct node { // Using 'typedef' saves lots of typing (and reading
int data;
struct node *next;
struct node *prev; // conventional layout of members
} node_t; // Notice '_t' as conventional suffix for user declared datatypes
node_t *print_nodes( node_t *head ) { // return pointer for use by caller
if( head ) { // insurance against NULL pointer
node_t *pn = head;
printf( "Forward: " ); // exercise circular LL in both directions
do {
printf( "%d ", pn->data );
pn = pn->next; // NB: 'next'
} while( pn != head ); // circular, not linear! One full circuit
puts( "" );
printf( "Reverse: " );
pn = pn->prev; // shift 'back' one node to begin
do {
printf( "%d ", pn->data );
pn = pn->prev; // NB: 'prev'
} while( pn != head->prev ); // circular, not linear! One full circuit
puts( "" );
}
return head;
}
node_t *createList() { // Create "one ring to rule them all"
int n = 0; // ALWAYS initialise variables
do {
printf( "Number of nodes (min 3): ");
scanf( "%d", &n ); // 'while' protects against bad input
} while( n < 3 );
node_t *head = NULL;
for( int i = 0; i < n; i++ ) {
printf( "Enter the element of node %d: ", i + 1 );
node_t *pn = (node_t *)calloc( 1, sizeof *pn ); // 'calloc()' zeros the block
/* check 'pn == NULL' omitted for brevity */
scanf("%d", &pn->data ); // read directly into destination (fewer variables)
if( head == NULL )
head = pn->prev = pn->next = pn; // 1st node, circular
else {
pn->prev = head->prev; // other nodes spliced-in ahead of 'head'
pn->next = head;
head->prev->next = pn;
head->prev = pn;
}
}
return head;
}
void freemem( node_t *head ) { // VERY important to respect "heap" storage!
if( head == NULL ) return;
node_t *pn = head; // traverse releasing nodes along the way
do {
node_t *pdel = pn;
pn = pn->next;
free( pdel );
} while( pn != head );
}
int main() {
// create, print, release, done...
freemem( print_nodes( createList() ) );
return 0;
}
Output
Number of nodes (min 3): 5
Enter the element of node 1: 42
Enter the element of node 2: 56
Enter the element of node 3: 10
Enter the element of node 4: -5
Enter the element of node 5: 256
Forward: 42 56 10 -5 256
Reverse: 256 -5 10 56 42
This code implements and proves a circular doubly linked list. The example can be trivially adapted to a linear dbl-LL by severing the connection between head and head->prev after the ring has been formed, and then making necessary adjustments at other locations to account for the change.

How to build a Linked_list_builder function in C

I am learning about linked list, I want to make a function which creates a linked list, after that I want to make a for loop which will print our linked list at main function.
I tried this:
#include <stdio.h>
#include <stdlib.h>
typedef struct linked_list {
int data;
struct linked_list* link;
}node;
//building list
node linked_list_builder(int length) {
node* list;
list = (node*) malloc(length * sizeof(node));
for(int i=0;i<length;i++)
{
printf("Data in list no.%d at index %d = ",i+1,i);
scanf("%d",list->data);
list->link += 1;
}
return *list;
}
int main() {
int length;
printf("Enter the length of Linked list:\n");
scanf("%d", &length);
node list = linked_list_builder(length);
//printing list
for(int i=0;i<length;i++)
{
printf("index %d->list %d = %d\n",i,i+1,list.data);
list.link++;
}
return 0
}
I don't know what's the exact problem, I don't know how can I return my linked list from function, and How can I actually travel it and print its data?
You have two problems:
As pointed out by #WhozCraig:
You are reserving space for all nodes at once, if that were possible, you would have no need to create a list (with its handicap of memory fragmentation and also needing an extra pointer to point to the next node) and in that case it would be enough to use an array.
A list is useful when you don't know the number of elements you need beforehand. If you really need a list, store the position of the first element of the list in a variable (head) and add elements to that list one by one through a push function:
node *linked_list_push(node *tail, int data) {
node *curr = calloc(1, sizeof(node));
curr->data = data;
if (tail != NULL) {
tail->link = curr;
}
return curr;
}
node *head = NULL, *tail = NULL;
// pushing list
for (int i = 0; i < length; i++) {
tail = linked_list_push(tail, i);
if (head == NULL) {
head = tail;
}
}
// printing list
while (head) {
node *temp = head;
printf("%d\n", head->data);
head = head->link;
free(temp);
}
And as pointed out by #Kuro:
scanf wants a pointer:
scanf("%d",list->data);
should be
scanf("%d",&list->data);

How to implement a [copy array to linked list] function?

What this supposed to do is:
Create an array with 4 elements.
Print these 4 elements.
Copy array elements to a created linked list in copy fucntion.
Print linked list with print and traverse fuction.
I tried this and it compiles, but crashes after printing the array.
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define ELEMENTS 4
struct node {
int data;
struct node *next;
};
struct node *head;
void insert(int x) {
struct node *temp = malloc(sizeof(struct node));
temp->data = x;
temp->next = NULL;
if (head != NULL)
temp->next = head;
head = temp;
}
void copy(struct node *head, int array[ELEMENTS], int n) {
//copying array elements and create linked list
struct node *temp = malloc(sizeof(struct node));
temp->data = array[0];
temp->next = NULL;
head = temp;
int i;
for (i = 1; i < n; i++) {
struct node *temp2 = malloc(sizeof(struct node));
temp->next = temp2;
temp2->data = array[i];
temp2->next = NULL;
temp = temp2;
}
}
void printlist() {
struct node*temp = head;
printf("List is : ");
while (temp->next != NULL) {
printf(" %d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
int *array = (int*)calloc(ELEMENTS , sizeof(int));
int i = 0;
for (i = 0; i < ELEMENTS; i++) {
printf("arrays = [%d] ", i);
scanf("%d", &array[i]);
}
for (i = 0; i < ELEMENTS; i++)
printf("array [%d] = %d \n", i, array[i]);
copy(head, array[ELEMENTS], ELEMENTS);
printlist();
getchar();
return(0);
}
How to fix it?
You dont need to pass head to the copy function because it is global and when you do you create a local pointer named head which gets destroyed as soon as function is over.
So copy should look like this
void copy(int array[ELEMENTS],int n) //copying array elements and create linked list
{
struct node*temp = malloc(sizeof(struct node));
temp->data=array[0];
temp->next=NULL;
head =temp;
int i;
for(i=1;i<n;i++)
{
struct node*temp2= malloc(sizeof(struct node));
temp->next= temp2;
temp2->data = array[i];
temp2->next = NULL;
temp=temp2;
}
}
Also while printing change while to
while(temp!=NULL)
{
printf(" %d ",temp->data);
temp=temp->next;
}
When you call the function copy, you are passing "array[ELEMENTS]" as an argument, but you want to pass only "array". What you're passing is value after your array, which the copy function is trying to interpret as an address of an array it's actaully expecting.
Note that accessing a value that is not yours like this results in undefined behaviour and can actually make the system kill your application. But what probably happened after is there will be a 0 in the memory, which gets passed to the copy function and it then tries to access values at memory 0x0 to 0xF, which almost always results in segmentation fault, which as you experienced first hand, causes the program to stop working.
Bottom line, delete [ELEMENTS] at the line where you call the copy function and I believe the program should start working. I implore you though to do further research on pointers and passing them as function parameters.
(And since I cannot comment yet I will just put this in here, as Sniper stated, you don't have to pass reference to global variable, but he is wrong about the structure being destroyed at the end of the function. That would have been true, if it was created at stack, but you are allocating space for it at heap, which means it will stay there until you either free() it or the program ends.)
I have simple dimple answer:
#include<stdio.h>
#include<stdlib.h>
struct Node{
int current;
struct Node *next;
};
struct LinkedList{
struct Node *head;
};
int main(){
int i, data[5] = {10, 20, 30, 40, 50};
struct Node *node = malloc(sizeof(struct Node));
struct LinkedList *llist = malloc(sizeof(struct LinkedList));
node->current = data[0];
node->next = NULL;
llist-> head = node;
for(i = 1; i <= sizeof(data) / sizeof(data[0]) - 1; i++){
struct Node *new_node = malloc(sizeof(struct Node));
node->next = new_node;
new_node->current = data[i];
new_node->next = NULL;
node = new_node;
}
node = llist->head;
printf("llist: ");
while(node != NULL){
printf("%d->", node->current);
node = node->next;
}
return 0;
}

Delete node after comparing it to left node

So I am writing this program when the node is deleted if it is greater than the node to the left to it, and finds the number of iterations after which no node is deleted. I came up with this, but the int daysalways remains at 0.
#include<stdio.h>
#include<malloc.h>
struct plants{
int val;
struct plants *next;
};
void printlist();
int main(){
int counter=0;
int size=0;
int days=0;
printf("Enter the number of plants\n");
scanf("%d",&size);
printf("Enter the amount of pesticide each plant has.\n");
struct plants* head = NULL;
while( counter < size )
{
struct plants * current = malloc(sizeof(struct plants));
scanf( "%d", &current->val);
current->next = head;
head = current;
counter ++;
}
struct plants *temp = head;
printf("You have entered.\n");
while(temp!=NULL){
printf("%d\t",temp->val);
temp=temp->next;
}
struct plants *now = head;
while(counter<size){
if(now->val < now->next->val){
struct plants* nextNext = now->next->next;
days++;
free(now->next);
now->next= nextNext;
counter++;
}
else{
now = now->next;
}
}
printf("The days after which the plants stop dying %d.\n",days);
}
You need a pointer to the pointer of the node which you want to delete, so you can put the successor node of the node to its place:
int days = 0;
struct plants **now = &head;
while( *now != NULL && (*now)->next != NULL ) // do as long as there are two nodes to compare
{
struct plants *next = (*now)->next; // successor of the node
if ( (*now)->val < next->val ) // test if successor node is greater than node
{
free( *now ); // free the node
*now = next; // put successor of the node in place of the node
}
else
{
now = &((*now)->next); // step one forward
days ++; // increment counter because no node was deleted
}
}
An other solution would be to remember the predecessor of the current node:
int days = 0;
struct plants *now = head; // start at head of list
struct plants *prev = NULL; // predecessor of head is NULL
while( now != NULL && now->next != NULL ) // do as long as there are two nodes to compare
{
struct plants *next = now->next; // successor of the node
if ( now->val < next->val ) // test if successor node is greater than node
{
free( now ); // free the node
if ( prev == NULL ) // put successor of the node in place of the node
head = next; // the first node of the list was deleted
else
prev->next = next; // successor of predecessor is predecessor of deleted node
now = next; // step one forward
// note "prev" does not change in this case
}
else
{
prev = now;
now = now->next; // step one forward
days ++; // increment counter because no node was deleted
}
}
Look:
while( counter < size )
{
struct plants * current = malloc(sizeof(struct plants));
scanf( "%d", &current->val);
current->next = head;
head = current;
counter ++;
}
//counter == size
struct plants *temp = head;
printf("You have entered.\n");
while(temp!=NULL){
printf("%d\t",temp->val);
temp=temp->next;
}
struct plants *now = head;
//counter == size
while(counter<size){
if(now->val < now->next->val){
struct plants* nextNext = now->next->next;
days++;
free(now->next);
now->next= nextNext;
counter++;
}
else{
now = now->next;
}
}
You didn't reset the value of counter

Linked list shows only first node element on printing

I am trying to create a linked list in order to enhance my concepts of pointers and address. I have to create linked list in following way:
(1) Read all the nodes together at once at terminal.
(2) Then show the final linked list so formed at last.
How i try to do so ?
I am reading first the size of linked list (total number of nodes to be entered). Then i read all the nodes 1 by one in do-while loop. After reading all the nodes i try to create linked list. I differentiate the case when the node is first node to be created by a count variable which will have count=0 when the node is first node after that it will be in another loop.
The output i get is as follows:
enter the size of node
4
start entering the number of elements until your size
2
3
4
5
Printing linked list
2-> //It don't print the other nodes, Just first one
hp#ubuntu:~/Desktop/pointer$
My full code to do so is :
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node * next;
};
typedef struct node node;
node * tree;
void main()
{
int size, data;
int count = 0; //this count flag is to check is it's first node or not inside the do-while loop.
tree = NULL;
printf("enter the size of node\n");
scanf("%d", & size);
printf("start entering the number of elements until your size\n");
node * temp3 = tree;
node * prev;
//Problem creating area is below
do
{
scanf("%d", & data);
if (count == 0)
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev = temp;
}
else if (count != 0)
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev-> next = temp;
}
size--;
++count;
}
while (size > 0);
printf("Printing linked list\n");
node * temp1;
temp1 = prev;
//there may be problem here
while (temp1-> next != NULL)
{
printf("%d-> ", temp1-> freq);
temp1 = temp1-> next;
}
printf("\n");
}
Couldanyone please help me in printing the full linked list by pointing me the error with it's solution ?
Okay there is some unnecessary pointers and a few pointer mistakes being made, for ease of answering I've rewritten your code, I'll try to explain what I did here:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node * next;
};
typedef struct node node;
//only need two pointers when building a linked list, one for the top and one for the
//current node
node *tree = NULL, *curr = NULL; //init both pointers to NULL initially
int main()
{
int size, data; //dont need count, you'll see in a minute why
printf("enter the size of node\n");
scanf("%d", & size);
printf("start entering the number of elements until your size\n");
//Problem creating area is below
do
{
scanf("%d", &data);
if (tree == NULL) //just test for top node being NULL instead of using count
{
node *temp;
temp = malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
//stylistically i like using curr rather than prev, just a style choice
tree = temp; //set tree to first node
curr = tree; //make the top node the current node
}
else //don't need else if, there are only two conditions
{
node *temp = malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
curr->next = temp; //set the next node in list to the new one
curr = curr->next; //here's where you had pointer issues, move the current
//to the newly created node
}
size--;
}
while (size > 0);
printf("Printing linked list\n");
curr = tree; //reuse curr, no need to make a new pointer
//test for the current node being NULL, takes care of special case of empty list
//causing a segfault when you attempt to access a member of an invalid pointer
while (curr != NULL)
{
printf("%d->", curr->freq);
curr = curr->next; //move to next item in list
}
printf("\n");
return 0;
}
I ran a sample run with size of 3 and inputs of 1, 2, and 3, and I get as output: 1->2->3->
You got two problems.
else if (count != 0)
{
node * temp = prev;
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev-> next = temp;
}
You aren't changing prev to point to your new node. It still points to '2' in your scenario, and you'll never have more than two nodes in the list.
Try something like
else if (count != 0)
{
/* node * temp = prev; */ //This code is not doing anything useful
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev-> next = temp;
prev = temp;
}
Next, your printing loop should probably be
node* temp1 = start; //You need a variable that points to the first node in the list
do
{
printf("%d-> ", temp1-> freq);
temp1 = temp1-> next;
}
//The last item will always have next == NULL, and must be included
while (temp1-> next != NULL);

Resources