Simple LInked list - c

I have the following single linked list,I always get the length as 1,even if i push 3 elements,and always only one node is created.Please help.Thanks.
#include <stdio.h>
struct node
{
int data;
struct node *next;
};
void push(struct node **head,int data)
{
struct node *temp = (struct node*)malloc(sizeof(struct node));
temp->data=data;
if(*head == NULL)
{
*head=temp;
}
else
{
temp->next=*head;
*head=temp;
}
}
int length(struct node *head)
{
struct node *temp = head;
int count=0;
if(temp !=NULL)
{
count++;
printf("%d",temp->data);
temp=temp->next;
}
return count;
}
int main()
{
int a;
struct node *head=NULL;
push(&head,1);
push(&head,2);
push(&head,3);
a=length(head);
printf("%d",a);
return 0;
}

Replace if by while in the length function

In your length function, change this line:
if(temp !=NULL)
to this:
while(temp != NULL)

Have you noticed the structure of your length method? You are using an if statement where a loop would be appropriate. You are getting the answer of 1 because you are only executing the count ++ statement once.
Hope this helps.

The error comes from push() function. If head is not null you need to iterate through the list to the last node. And as said before while instead if

# include <stdlib.h>
void push(struct node **head,int data)
{
struct node *temp;
temp = malloc (sizeof *temp);
temp->data = data;
temp->next = *head;
*head = temp;
}

Related

Linked list in c returns negative number instead of adding node

Can someone explain to me why this code returns a random negative number instead of adding the node as it should? If the call to addnode is removed the main function works as it should so the problem lies with the addnode function. I don't think it's malloc that has the problem and I can't for the life of me figure out what is. Please help, I'm an amateur at c and I have a vague understanding of how pointers work so I guess something's wrong with my pointers. Here's the full code :
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
int addNode(struct node **head, int value);
void printList(struct node **head);
int main()
{
int value;
struct node *head;
head=NULL;
//int isempty(struct node *head);
for(int i=0;i<10;i++)
{
printf("\nInsert node value :");
scanf("%d",&value);
addNode(&head,value);
}
printList(&head);
return 0;
}
int addNode(struct node **head,int value)
{
struct node *newnode;
newnode=(struct node *) malloc(sizeof(struct node));
//if(newnode==NULL)
if(!newnode)
{
printf("Memory allocation error \n");
exit(0);
}
if(*head=NULL)
{
newnode->data=value;
newnode->next=NULL;
*head=newnode;
return 1;
}
else
{
struct node *current;
*current = **head;
while(current != NULL)
{
if(value<=(current->data)){
//περίπτωση 1ου κόμβου σε μη κενή λίστα
if(current==*head){
newnode->data=value;
newnode->next=*head;
*head=newnode;
return 1;
}
//περίπτωση ενδιάμεσου κόμβου
newnode->data=value;
return 1;
}
current = current->next;
}
}
}
/*int isempty(struct node *head){
return (head==NULL);
}*/
void printList(struct node **head) {
struct node *ptr = *head;
printf("\n[ ");
//start from the beginning
while(ptr != NULL) {
printf("(%d) ",ptr->data);
ptr = ptr->next;
}
printf(" ]");
return;
}
Well for starters you are having an assignment instead of a comparison in addNode
if(*head=NULL) should be if(*head==NULL)
Other than that, I think you are trying to maintain the elements in a sorted manner? But in any case you are manipulating pointers a bit more than you need to.

linked list of strings in C

I am trying to create a linked list of strings in C and have had problems adding the first Node into the list. For whatever reason my program prints NULL even though I reference the head variable to newNode but it does not copy the string from struct pointer to struct pointer. Any help is appreciated. Thanks!
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
typedef struct stringData {
char *s;
struct stringData *next;
} Node;
Node *createNode(char *s) {
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->s = s;
newNode->next = NULL;
return newNode;
}
void insert(Node *head, Node *newNode) {
if (head == NULL) {
head->s = newNode->s;
head = newNode;
}
}
void printList(Node *head) {
while (head != NULL) {
printf("%s\n", head->s);
head = head->next;
}
}
int main()
{
Node *head = createNode(NULL);
Node *a = createNode("A");
insert(head, a);
printList(head);
return 0;
}
Following code snippet is wrong:
void insert(Node *head, Node *newNode) {...}
...
insert(head, a);
You need to pass the pointer by reference. Currently you are changing local copy (argument).
Fix
Change your insert as:
void insert(Node **head, Node *newNode) {...}
And call as:
insert(&head, a);
What elseAtleast insert (and possibly) more functions are not fool-proof (guaranteed null pointer dereference, else case not handled etc). You need to debug and fix many such cases. Working your approach properly on paper before coding may help.
Here is a modified version of the code that gives an example of inserting new nodes at both the start of a list and the end of a list. In fact, the insert function could be used to insert a new node at any position in the list, since all it needs is a pointer to a link and a pointer to the node to be inserted.
#include <stdlib.h>
#include <stdio.h>
typedef struct stringData {
char *s;
struct stringData *next;
} Node;
Node *createNode(char *s) {
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->s = s;
newNode->next = NULL;
return newNode;
}
void insert(Node **link, Node *newNode) {
newNode->next = *link;
*link = newNode;
}
void printList(Node *head) {
while (head != NULL) {
printf("%s\n", head->s);
head = head->next;
}
}
int main(void)
{
Node *head = NULL;
Node *tail = NULL;
Node *n;
n = createNode("B");
// First node at start of list - head is updated.
insert(&head, n);
// First node is also the tail.
tail = n;
n = createNode("A");
// Insert node at start of list - head is updated.
insert(&head, n);
n = createNode("C");
// Insert node at end of list.
insert(&tail->next, n);
// Update tail.
tail = n;
printList(head);
return 0;
}

Linked string list in c

I'm trying this simple code which asks a user for string input. As it receives an input it then tries to copy each element of the string into different location in a linked list. Everything works just fine (I think) but when i print the linked list, the screen doesnt show any out put. Any idea why is this happening?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node {
char data;
struct node* next;
};
struct node* head = NULL;
void insert(char);
void print();
void main() {
char str1[20];
int i;
printf("Enter the string\n");
fgets(str1,20,stdin);
int len = strlen(str1);
printf("%d\n",len);
for(i=0;i<len;i++) {
insert(str1[i]);
}
print();
}
void insert(char str) {
struct node* temp = (struct node*)malloc(sizeof(struct node));
struct node* temp1 = head;
while(temp1!=NULL) {
temp1 = temp1->next;
}
temp->data = str;
temp1 = temp;
}
void print() {
struct node *temp;
temp = head;
while(temp!=NULL) {
printf("%c ",temp->data);
temp = temp->next;
}
}
You never set head to anything, it will always be NULL. So, you're not creating a list, but a group of unlinked floating nodes.
On another note, don't cast the result of malloc
On yet another note, no need to go through the entire list for every insert - you can keep a tail pointer along with the head, so adding to the end is done without a loop.
void insert(char str) {
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->data = str;
temp->next = NULL;
if(head){//head != NULL
struct node* temp1 = head;
while(temp1->next != NULL) {//search last element
temp1 = temp1->next;
}
temp1->next = temp;//insert new node
} else {
head = temp;//if head == NULL then replace with new node
}
}

Linked lists, how to insert if head does not exist?

I got a linked list, which should save the Outcome (W or L) and the gained/lost points for each match. All good so far, but I'm getting trouble when the head does not exist/is empty. I also realized I have a pretty bad overview of how to implement linked lists, anyone got good and understandable resources? Anyway this is my code:
#include <stdio.h>
#include <stdlib.h>
struct node {
int point;
char outcome;
struct node *next;
};
void add(struct node *data){
if(data == NULL){
data = malloc(sizeof(struct node));
printf("Outcome and points?\n");
int point;
char outcome;
scanf("%c %d",&outcome,&point);
fgetc(stdin);
data->point=point;
data->outcome=outcome;
data->next=NULL;
}else{
struct node *current= data;
while(current->next != NULL){
current = current->next;
}
current->next = malloc(sizeof(struct node));
current=current->next;
printf("Outcome and points?\n");
int point;
char outcome;
scanf("%c %d",&outcome,&point);
fgetc(stdin);
current->point=point;
current->outcome=outcome;
current->next=NULL;
}
}
void print(struct node *data){
struct node *current = data;
while(current != NULL){
printf("%c with %3d\n",current->outcome,current->point);
current = current->next;
}
}
int main()
{
struct node *head=NULL;
add(head);
add(head);
add(head);
print(head);
}
Any help would be appreciated :)
When you execute:
void add(struct node *data){
if(data == NULL){
data = malloc(sizeof(struct node));
the value of head does not change in the calling function.
Suggest a change of strategy.
struct node* add(struct node *head)
{
if(head == NULL){
head = malloc(sizeof(struct node));
printf("Outcome and points?\n");
int point;
char outcome;
scanf("%c %d",&outcome,&point);
fgetc(stdin);
head->point=point;
head->outcome=outcome;
head->next=NULL;
}else{
struct node *current= head;
while(current->next != NULL){
current = current->next;
}
current->next = malloc(sizeof(struct node));
current=current->next;
printf("Outcome and points?\n");
int point;
char outcome;
scanf("%c %d",&outcome,&point);
fgetc(stdin);
current->point=point;
current->outcome=outcome;
current->next=NULL;
}
return head;
}
And, then change the usage:
int main()
{
struct node *head = add(NULL);
add(head);
add(head);
print(head);
}
You can simplify the code by starting the list with an anchor node. An anchor node is a node that is only used for its next pointer. In the code below, the call to calloc creates the anchor node, and sets all of the fields in the anchor to 0. In other words, a node is created with next == NULL.
Note that when printing the list, the for loop starts by skipping the anchor node with for (list = list->next;...)
#include <stdio.h>
#include <stdlib.h>
struct node
{
int point;
char outcome;
struct node *next;
};
void add( struct node *list )
{
struct node *data;
data = malloc(sizeof(struct node));
data->next = NULL;
printf("Outcome and points?\n");
scanf("%c %d",&data->outcome,&data->point);
fgetc(stdin);
while (list->next != NULL)
list = list->next;
list->next = data;
}
void print( struct node *list )
{
for (list = list->next; list != NULL; list = list->next)
printf("%c with %3d\n", list->outcome, list->point);
}
int main()
{
struct node *head = calloc( 1, sizeof(struct node) );
add(head);
add(head);
add(head);
print(head);
}
Side note: I've omitted some error checking to keep things simple, you should really be checking the return values from calloc, malloc, and scanf and handle any errors. And, of course, you should free all of the nodes at the end.

What is wrong with my code for singly linked list?

I'm working on a singly linked list in C. This is what I've written so far.
C program
#include<stdio.h>
#include<stdlib.h>
struct Node{
int value;
struct Node *next;
};
struct Node* init()
{
struct Node* head=NULL;
head=malloc(sizeof(struct Node));
head->value=-1;
return head;
}
int length(struct Node* head)
{
struct Node* current=head;
int length=0;
while(current!=NULL)
{
length++;
current=current->next;
}
return length;
}
void print(struct Node* head)
{
int i=0;
int len=length(head);
for(i=0;i<len;i++)
{
printf("%d%d",i,head[i].value);
printf("\n");
}
}
struct Node* insert(int data,struct Node* head)
{
struct Node* current=NULL;
if(length(head) > 0)
{
int val=head->value;
if (val==-1)
{
head->value=data;
head->next=NULL;
}
else
{
current=malloc(sizeof(struct Node));
current->value=data;
current->next=head;
head=current;
}
}
else
{
printf("List is empty");
}
return head;
}
int main()
{
/* printf("Hello"); */
struct Node *head=init();
head=insert(20,head);
head=insert(30,head);
head=insert(40,head);
print(head);
printf("%d",length(head));
return 0;
}
The output values I get are:
Index Value
0 40
1 0
2 0
and for length is 3. I'm not able to grasp what I'm doing wrong here in pointer manipulation.
One obvious problem is not setting next to NULL on init - that would fail when checking length on the empty list
But your real problem is the print function
You can't use:
head[i].value
That notation is only valid for arrays, you need to use next to find each member
The Init function should set Next to NULL
struct Node* init()
{
struct Node* head=NULL;
head=malloc(sizeof(struct Node));
head->value=-1;
head->next=NULL;
return head;
}
otherwise the first call to length return an undefined result ( or GPF ).
Here:
for (i = 0; i < len; i++)
{
printf("%d%d", i, head[i].value);
printf("\n");
}
You need to advance from one node to another with head = head->next in the same manner as you do it in length(). head[i] won't do it.
It's unclear why your init() and insert() are so unnecessarily complicated and I don't even want to try to guess why. I want to suggest a better insert() and no init():
struct Node* insert(int data, struct Node* head)
{
struct Node* current;
current = malloc(sizeof(struct Node));
current->value = data;
current->next = head;
return current;
}
And then you do this:
int main(void)
{
struct Node *head = NULL;
head = insert(20, head);
head = insert(30, head);
head = insert(40, head);
print(head);
printf("%d", length(head));
return 0;
}
The notation head[i].value is only valid for arrays but not for linked lists. Arrays and linked lists are completely different, allocation of memory towards arrays is premeditated where as for linked lists it's dynamic. That is the reason why we use pointers for linked lists.
In init() you didn't assign null which causes the loop to run infinite times when you call length() for first time.
I am posting the modified code of print function:
void print(struct Node* head)
{
int i=0;
int len=0;
struct Node* current=head;
for(i=0;i<len;i++)
{
printf("%d %d",i,current->value);
print("\n");
current=current->next;
}
}

Resources