Having trouble with a simple linked list in C - c

I'm trying to understand linked lists. I created this code which is supposed to give me experience with linked lists. When I run this code I get 0, though the output should be 10,9,8,7,6,5,4,3,2,1,0. Could someone help me figure this out?
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int value;
struct node *next;
}node;
node * addnode (node *ptr, int value);
void traverse(node *ptr);
int main (void)
{
int i;
node *ptr,*root;
root=(node *)malloc(sizeof(node));
ptr=root;
root->value=0;
root->next=0;
for(i=1;i>10;i++)
ptr=addnode(ptr,i);
traverse(ptr);
return(0);
}
void traverse(node *ptr)
{
printf("%d\n",ptr->value);
if(ptr->next) /*assuming that the pointer to the next node is initialized to NULL, so if its NULL then the if codeblock won't execute*/
traverse(ptr->next);
}
node * addnode (node *ptr, int value)
{
node *newnode;
newnode=(node *)malloc(sizeof(node));
newnode->value=value;
newnode->next=ptr;
return(newnode);
}

There are two problems with your code:
Ideally, you would do traverse(root) instead of traverse(ptr).
You are adding nodes at the beginning of your linked list, when you should add them on the end of the list.
You can do it like this (source):
void Push(struct node** headRef, int newData) {
struct node* new_node =
(struct node*) malloc(sizeof(struct node));
new_node->data = newData;
new_node->next = *headRef;
*headRef = new_node;
}
which in your case would look like:
void addnode(struct node** headRef, int newData) {
struct node* new_node =
(struct node*) malloc(sizeof(struct node));
new_node->value = newData;
new_node->next = *headRef;
*headRef = new_node;
}
Then you add nodes like this: addnode(&root, some_value);

Related

I can not pass by reference my node

I dont want create general *head node and I want to pass by reference and chance my data but although create new node for next node I cant reach my new node on main.
İf I look n1.next in main I see it is null.Why ?What is wrong ?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node{
int data;
struct node* next;
};
void add(struct node** head,int data){
struct node * tmp = *head;
while(tmp != NULL){
tmp = tmp->next;
}
tmp = (struct node*) malloc(sizeof(struct node));
tmp->data= data;
tmp->next=NULL;
}
int main()
{
struct node n1;
n1.data=5;
n1.next=NULL;
add(&(n1.next),15);
printf("%d",n1.next->data);
return 0;
}
Instead of using a head pointer, are you trying to pass in the last next pointer in the list, and then update that to point to your new node? If so, add() should be
void add(struct node** head, int data) {
struct node* p = malloc(sizeof(*p));
p->data = data;
p->next = NULL;
*head = p;
}

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;
}

Accessing fields of a struct for a double linked list

I want to make a double linked list and I have a problem with accessing fields in the struct. This is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int val;
struct node * next;
struct node * prev;
}node;
void insert(int val, node **head)
{
node * temp= *head;
node * temp2=(node *)malloc(sizeof(node));
node * temp3=(node *)malloc(sizeof(node));
temp2->val=val;
temp2->prev=NULL;
temp2->next=*head;
*head=temp2;
temp2->next->prev=temp2;
}
void print(node* head)
{
node* temp=head;
while(temp!=NULL)
{
printf("%d ", temp->val);
temp=temp->next;
}
}
int main()
{ node * head=NULL;
insert(1, &head);
insert(2, &head);
print(head);
return 0;
}
I get a crash at temp2->next->prev, and I don't understand why. Am I not allowed to access the prev field of the temp2->next node? I tried writing (temp2->next)->prev but also doesn't work. Is there any way that I cant make that work?
When you insert the first node, *head, and therefore temp->next, is NULL. Check that case:
void insert(int val, node **head)
{
node *temp= malloc(sizeof(*temp));
temp->val = val;
temp->prev = NULL;
temp->next = *head;
*head = temp;
if (temp->next) temp->next->prev = temp;
}
(I've removed the unused variables and lost the cast on malloc.)
A doubly linked list should probably have a tail, too. In that case, update the tail when you append an item at the head of an empty list.
try this:
void insert(int val, node **head)
{
if(*head == NULL){
node * temp2=(node *)malloc(sizeof(node));
temp2->val=val;
*head = temp2;
}
else{
node * temp= *head;
node * temp2=(node *)malloc(sizeof(node));
temp2->val=val;
temp2->prev=NULL;
temp2->next=temp;
temp->prev = temp2;
}
}
Most likely head was not initialized
As I have understood you always insert a new node before the head though in double linked list you have to add new nodes usually at the tail of the list. As a double linked list usually have two sides then there is a sense to define two functions: push_front and push_back. Your function insert corresponds to function push_front.
Nevertheless function insert could look the following way
void insert( int val, node **head )
{
node *temp = ( node * )malloc( sizeof( node ) );
temp->val = val;
temp->prev = NULL;
temp->next = *head;
if ( *head ) ( *head )->prev = temp;
*head = temp;
}
It would be better if you would define one more structure named as for example List (or whatever) and that could be defined as
struct List
{
node *head;
node *tail;
};
Also you could add one more data member - a count of the nodes in the list, For example
struct List
{
node *head;
node *tail;
size_t count;
};
Also do not forget to write a function that would delete all nodes of the list when it is not needed any more.

Inserting a node at the end of a doubly linked list

I tried inserting node at the end of doubly-linked list with a insert function but the process execution stops abruptly after second insertion. I tried checking out address of all pointer variable used in insert function and they show that my code works fine until the third insert function. How can I fix my code?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
struct node* prev;
};
void insert(struct node** header,int data) {
struct node* newnode=(struct node*)malloc(sizeof(struct node*));
newnode->data=data;
newnode->prev=NULL;
newnode->next=NULL;
if(*header == NULL) {
*header=newnode;
return;
}
struct node* temp = *header;
while(temp->next != NULL) {
temp=temp->next;
}
temp->next = newnode;
newnode->prev = temp;
printf("%d\n**\n", temp->next);
}
void main() {
struct node* head = NULL;
insert(&head, 4);
insert(&head, 45);
printf("\n main head %d", head);
insert(&head, 8);
printf("testing");
insert(&head, 69);
}
You are not allocating enough memory
struct node* newnode=(struct node*)malloc(sizeof(struct node*));
// here you allocate only 4 bytes (or 8 bytes on a 64 bit system)
should be:
struct node* newnode = (struct node*)malloc(sizeof(struct node));
Then everything works fine.

Linked list implementation in c without using double-pointer

I have implemented a simple linked list in C language, but can it be implemented without using double-pointer(**).I want to implement same program by using only single pointers.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
void push(struct node** head_ref, int new_data)
{
struct node* new_node = (struct node*) malloc(sizeof(struct node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void append(struct node** head_ref, int new_data)
{
struct node* new_node = (struct node*) malloc(sizeof(struct node));
struct node *last = *head_ref; /* used in step 5*/
new_node->data = new_data;
new_node->next = NULL;
if (*head_ref == NULL)
{
*head_ref = new_node;
return;
}
while (last->next != NULL)
last = last->next;
last->next = new_node;
return;
}
void printList(struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->next;
}
}
int main()
{
struct node* head = NULL;
append(&head, 6);
push(&head, 7);
push(&head, 1);
append(&head, 4);
printf("\n Created Linked list is: ");
printList(head);
getchar();
return 0;
}
Is it possible to replace "struct node** head_ref" with "struct node* head_ref"?
Changed code after suggestions(still not getting output)
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node* push(struct node* head, int new_data)
{
struct node* new_node = (struct node*) malloc(sizeof(struct node));
new_node->data = new_data;
new_node->next = head;
head = new_node;
return head;
}
struct node* append(struct node* head, int new_data)
{
struct node* new_node = (struct node*) malloc(sizeof(struct node));
struct node *last = head; /* used in step 5*/
new_node->data = new_data;
new_node->next = NULL;
if (head == NULL)
{
head = new_node;
return head;
}
while (last->next != NULL)
last = last->next;
last->next = new_node;
return head;
}
void printList(struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->next;
}
}
int main()
{
struct node* head = NULL;
head= append(&head, 6);
head=push(&head, 7);
head=push(&head, 1);
head=append(&head, 4);
printf("\n Created Linked list is: ");
printList(head);
getchar();
return 0;
}
Yes, you can rewrite this code using only single pointers, but you would have to change the semantic of your API and the pattern in which it is used.
Essentially, you replace the second level of indirection in
void push(struct node** head_ref, int new_data)
with a client-side assignment, i.e.
struct node* push(struct node* head, int new_data)
This means that instead of
push(&head, num);
the caller will have to write
head = push(head, num);
Same goes for the implementation of append.
Replace (&head,6) with (head,6).As you are not passing the address of the head, on receiving end you have push(struct node* head, int new_data).Rest all have been clarified by above given answer
Another solution is to create an empty node called head, and then create a pointer to that node called list. You can then pass list to all of the functions, like this
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
void push(struct node *list, int new_data)
{
struct node* new_node = malloc(sizeof(struct node));
new_node->data = new_data;
new_node->next = list->next;
list->next = new_node;
}
void append(struct node *list, int new_data)
{
while ( list->next != NULL )
list = list->next;
push( list, new_data );
}
void printList(struct node *node)
{
for ( node=node->next; node != NULL; node=node->next )
printf(" %d ", node->data);
printf( "\n" );
}
int main( void )
{
struct node head = { 0, NULL };
struct node *list = &head;
append(list, 6);
push(list, 7);
push(list, 1);
append(list, 4);
printf("\n Created Linked list is: ");
printList(list);
getchar();
return 0;
}

Resources