How to loop over a linked-list in c - c

I am trying to create a function that turns an array to a linked list for further usage
typedef struct ListNode {
int val;
struct ListNode *next;
} ListNode;
ListNode * create_linked_list(int *nums , int count)
{
ListNode * ptr = (ListNode*)malloc(count*sizeof(ListNode));
for (int i =0; i < count; i++)
{
ListNode new;
new.val = nums[i];
ptr[i] = new;
}
for (int j=0; j < count; j++)
{
if ( j>=count )
ptr[j].next = NULL;
else
ptr[j].next = &ptr[j+1];
}
return ptr;
}
int main()
{
int nums[] = {2,4,3};
ListNode *node_ptr = create_linked_list(nums , sizeof(nums)/sizeof(nums[0]));
ListNode start = node_ptr[0];
}
I have this simple function that turns an array of integers into a linked list, assume the last node in the list is called x_node now x_node.next is equal to NULL because it is defined inth the second for loop in create_linked_list, but when I try to add a while loop in the main it results in a segmentation fault
int main()
{
int nums[] = {2,4,3};
ListNode *node_ptr = create_linked_list(nums , sizeof(nums)/sizeof(nums[0]));
ListNode start = node_ptr[0];
while (start.next != NULL)
{
printf("%d \n", start.val);
start = *start.next; // at the last element it should stop but a segfault is thrown
}
}

If you wan t to loop over a linked list, you need to create the list properly in the first place. Your create_linked_list function is totally wrong.
You want this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct ListNode {
int val;
struct ListNode* next;
} ListNode;
ListNode* create_linked_list(int* nums, int count)
{
ListNode* head = NULL;
ListNode *previous = NULL;
for (int i = 0; i < count; i++)
{
// create new node and put value into it
ListNode *new = malloc(sizeof(ListNode));
new->val = nums[i];
new->next = NULL;
if (i == 0) // head will point to the first element
head = new;
if (previous)
{
// if previous node exists, link to newly created node
previous->next = new;
}
previous = new; // new node becomes previous node
}
return head;
}
int main()
{
int nums[] = { 2,4,3 };
ListNode* head = create_linked_list(nums, sizeof(nums) / sizeof(nums[0]));
// now it's up to you to write the print_list function
// print_list(head);
}
Now writing the print_list function should be easy. Hint: take a pencil and a piece if paper and draw the nodes with arrows as pointers pointing to the next node.

Related

How to print the first node from a linked list of structs?

Below is a Minimal Reproducible Example from my code. What I am doing is that I am inserting data in a list of structs and printing them on the console.
I want to print from each link only the first element that is inserted into each list of structs.
But how is that possible when instead of data in my struct I have:
typedef struct Node
{
int rollnumber, src, dst;
double gentime;
struct Node *next;
} Node;
(rollnumber, src, dst,gentime are the information I am reading from text files, but the reading code is not nessacary, so I wrote it with testdata.)
MINIMAL REPRODUCIBLE EXAMPLE
#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct Node
{
int data;
struct Node* next;
} Node;
int push_front(Node** head, int data)
{
Node* new_node = malloc(sizeof(Node));
int success = new_node != NULL;
if (success)
{
new_node->data = data;
new_node->next = *head;
*head = new_node;
}
return success;
}
void output(Node* head)
{
for (Node* current = head; current != NULL; current = current->next)
{
printf("%d ", current->data);
}
}
void display(Node** set, int i)
{
output(set[i]);
putchar('\n');
}
int main(void)
{
int testdata = 1;
Node* link[N] = { 0 };
struct Node* head = NULL;
for (int i = 0; i < N; i++) {
push_front(&link[i], testdata++);
push_front(&link[i], testdata++);
}
for (int i = 0; i < N; i++) {
printf("link[%d]:", i);
display(link, i);
}
}
If you only want to print the first element of each link list, just do not loop in output:
void output(Node* head)
{
printf("%d ", head->data);
}
If I am right you want the first element of the list right ??
If so than the way you are working you are pushing the new node in front of old node, so your first node is now the last in the line, so all you need to do is to iterate the list till Node* next == null, and that node will be your answer
Node *getLastInLine( Node *Head){
Node *ptr;
ptr = Head;
if( ptr == NULL) return NULL;
while(ptr-> next != NULL){
ptr = ptr->next;
}
return ptr;
}

Trouble declaring an adjacency list in C

It's the very first time I am trying to use a adjacency list and I am really confused with its declaration
This is my node structure and the list for using as my first node, what I called head
typedef struct node
{
int NodeNum;
struct node *next;
}node;
typedef struct list
{
node *head;
}list;
and here is where I try to allocate the correct amount of memory for the array of heads that the user wants
int n;
scanf("%d", &n);
list *NodList[n] = {0};
for(int i = 0; i < n; i++)
{
NodList[i] = (list*)malloc(sizeof(list));
NodList[i]->head = NULL;
}
Here is the thing, I want the user to tell me how many nodes I'll have and then allocate the correct amount of memory for it, but apparently I am getting something wrong here
Expanding a little bit on Antonin GAVREL's answer. Basically using the same linked list he brought up, and introducing an AListEntry used to represent the adjacency list. Each AListEntry points to a vertex and that vertex's adjacent vertices. It also points to the next AListEntry.
You could, instead, also just replace the AListEntry with a dynamically allocated array of Node pointers if you know the number of vertices ahead of time. Each index in the array will correspond to a vertex, and the pointer will point to the head Node pointer of your adjacent vertices for that vertex, which will a linked list. You'll end up with an array of linked lists.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int value;
struct Node* next;
} t_Node;
t_Node* createNode(int value)
{
t_Node* node = (t_Node*)malloc(sizeof(t_Node));
node->value = value;
node->next = NULL;
return node;
}
t_Node* addNode(int value, t_Node* node)
{
node->next = createNode(value);
return node->next;
}
typedef struct AListEntry
{
t_Node* vertex;
t_Node* adjacentVertices;
struct AListEntry* next;
} t_AListEntry;
t_AListEntry* createAListEntry(
t_Node* vertex,
t_Node* adjacentVertices)
{
t_AListEntry* entry = (t_AListEntry*)malloc(sizeof(t_AListEntry));
entry->vertex = vertex;
entry->adjacentVertices = adjacentVertices;
entry->next = NULL;
return entry;
}
void printAListEntries(t_AListEntry* aList)
{
while (aList != NULL)
{
printf("%d -> [ ", aList->vertex->value);
t_Node* node = aList->adjacentVertices;
while (node != NULL)
{
printf("%d ", node->value);
node = node->next;
}
printf("]\n");
aList = aList->next;
}
}
int main()
{
t_Node* v1 = createNode(1);
t_Node* v1Adjacents = createNode(2);
addNode(3, v1Adjacents);
t_AListEntry* aList = createAListEntry(v1, v1Adjacents);
t_Node* v2 = createNode(2);
t_Node* v2Adjacents = createNode(1);
addNode(3, v2Adjacents);
aList->next = createAListEntry(v2, v2Adjacents);
t_Node* v3 = createNode(3);
t_Node* v3Adjacents = createNode(1);
addNode(2, v3Adjacents);
aList->next->next = createAListEntry(v3, v3Adjacents);
printAListEntries(aList);
return 0;
}
Example where the array is declared on the stack as a VLA:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct Node
{
int value;
struct Node *next;
} t_Node;
bool build_linked_list(t_Node **head, int n) {
t_Node *node;
t_Node *tmp;
static int a = 1024; // just for test purposes
if (!(node = (t_Node*)malloc(sizeof(t_Node))))
return false;
node->value = a;
*head = node;
for(int i = 1; i < n; i++)
{
if (!(tmp = (t_Node*)malloc(sizeof(t_Node))))
return false;
tmp->value = i + a;
node->next = tmp;
node = tmp;
}
a <<= 1; // so that other nodes have different values
return true;
}
int main(void) {
int n;
scanf("%d", &n);
t_Node *nodes[n];
for (int i = 0; i < n; i++) {
if (!build_linked_list(&nodes[i], n)) {
perror("Failed to malloc node");
return 1;
}
}
for (int i = 0; i < n; i++) {
while (nodes[i]) {
printf("%d\n", nodes[i]->value);
nodes[i] = nodes[i]->next;
}
}
return 0;
}
Let me know if you have any question

How to print Linked List in C?

#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node, *LinkedList;
void CreateList(LinkedList N, int n)
{
N = (LinkedList)malloc(sizeof(Node));
N->next = NULL;
LinkedList new = N;
Node *p;
for (int i = 0; i < n; ++i) {
p = (Node *)malloc(sizeof(Node));
scanf("%d", &(p->data));
new->next = p;
new = p;
}
new->next = NULL;
}
int main()
{
LinkedList list;
CreateList(list, 20);
printf("%d", list->data);
return 0;
}
As you can see, I want to create a linkedlist and make it a function.
But when I "printf" linkedlist's data, it can't appear what i want.
Can you help me?
The direct problem, as M. Oehm notes, is that you pass the list object to the create function. The create function creates the list, but because the list object is not returned to main, main cannot see the list. To achieve what you want, do:
In main, declare the list as:
LinkedList *N; // a pointer
declare create as:
void CreateList(LinkedList **N, int n) // address of a pointer that receives the value
and dereference it in create:
*N = malloc(sizeof(Node)); // assign the value to the pointer in main
and now call it from main as:
CreateList(&N, 20); // pass the address of the pointer
I further note that you pass create an int, the number of elements in the list, but a list is typically made for an unknown number of elements. So you should read until end-of-file.
(All other required modifications in create I leave to you.)
Thank you all!! I solved this problem, and this is my code.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node;
void create(Node* *head, int n)
{
*head = malloc(sizeof(Node));
(*head)->next = NULL;
Node* new = *head;
Node* p;
for (int i = 0; i < n; ++i) {
p = malloc(sizeof(Node));
scanf("%d", &(p->data));
new->next = p;
new = p;
}
}
int main()
{
Node* list;
create(&list,20);
printf("%d", ((list->next)->next)->data); //for test
return 0;
}

Linked List Pointer Without A Cast Error

I'm getting assignment makes pointer from integer without a cast errors on lines 46 and 53, the two lines with double asterisks on either side, and for the life of me, I cannot figure out why. Linked lists are very new to me, I don't know how they work completely yet.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct node_def
{
int data;
struct node_def *next;
};
typedef struct node_def node;
node *makeNode (int a);
node *insertFront(node *head,node *new);
void printList(node *head);
int numNodes = 0;
int main()
{
srand(time(0));
int r = rand() % 10000;
int i = 0;
node *head = NULL;
node *tmp = NULL;
printf("How many nodes? ", numNodes);
scanf("%d", numNodes);
printf("\n");
head = insertFront(head, tmp);
for(i = 0; i < numNodes; i++)
{
makeNode(r);
printList(head);
}
printf("\n");
return 0;
}
node *makeNode (int a)
{
node *new = malloc(sizeof(node));
**new = a;**
return new;
}
node *insertFront(node *head, node *new)
{
**new->data = head;**
new->next = new;
return 0;
}
void printList(node *head)
{
int j = 0;
for(j = 0; j < numNodes; ++j)
{
while (head != NULL)
{
printf(" %4d", head->data);
head = head->next;
}
if(j % 10 == 0)
printf("\n");
}
return;
}
new = a is meant to make new nodes and assign them a random number from 0 - 9999.
You try to assign r to new, but new is a struct.
You make a pointer to struct : node *new
What you want to do is assigning r to new->data, which is an int.
node *insertFront(node *head, node *new)
{
**new->data = head;** // ** is meaningless
new->next = new; // new is a reserved key word, don't use it this way
return 0;
}
What you try to do is to put a NULL pointer as the head of your list.
Just push element into it within your makeNode function.
insert like this :
void createNode(node *head)
{
Node *new_node = malloc(sizeof(Node*));
new_node->data = rand() % 100000;
new_node->next = NULL;
if(head == NULL)
head = new_node;
else if(head != NULL)
//Here you have to adapt your list, search (linked list crud functions)
}
You have a bad understanding about what pointers are.
Hope it helps bro

Array to List in C (iteratively)

Using the typedefinitions:
typedef struct Node *List;
typedef struct Node {
int item;
List next;
} Node;
The recursive solution I found:
List arrayToList(int arr[],int n,int idx) {
if (n==idx) return NULL;
List list=malloc(sizeof(Node));
list->next=arrayToList(arr,n,idx+1);
list->item=arr[idx];
return list;
}
UPDATE: The following is almost correct, but I don't know why a zero is printed in the end.
List newNode() {
List li=malloc(sizeof(Node));
return li;
}
List arrayToList(int arr[],int n) {
List li=newNode();
List li1=li; /*save the beginning of the list*/
int i;
for (i=0;i<n;i++) {
li->item=arr[i];
li->next=newNode();
li=li->next;
}
li=NULL;
return li1;
}
void printList(List li) {
while (li!=NULL) {
li=li->next;
}
printf("\n");
}
int main(int argc, char* argv[]) {
int arr[]={4,1,2,3,4,7,4,5,6,8};
List li=arrayToList(arr,10);
printList(li);
return 0;
}
The output I get is: 4 1 2 3 4 7 4 5 6 8 0 .
UPDATE 2: Changing the function printList into this one gives me correct output:
void printList(List li) {
while (li->next!=NULL) {
printf("%d ",li->item);
li=li->next;
}
printf("\n");
}
But I'm left wondering why should I have li->next!=NULL as guard?
Do this:
typedef struct node {
int data;
struct node *next;
} Node;
Note that you want next to point to the next node, not list.
Node* arrayToList(int arr[],int n,int idx) {
if (n==idx) return NULL;
Node* headOfList = (Node*) malloc(sizeof(Node));
Node* tail = headOfList;
int i = n;
for(; i < idx; i++) {
// Create node
Node* node = (Node*) malloc(sizeof(Node));
node->data = arr[i];
node->next = NULL;
// Link Node to current list
tail->next = node;
tail = node;
}
return headOfList;
}
This is just a rough draft (I've not tried it out with a compiler), but the idea is there.
Initialize your first element:
Node *head = (Node*) malloc(sizeof(Node));
head->data = arr[0];
You will need a pointer to keep track of your current position:
Node *curr = head;
Create a for loop:
for(int i = 1; i < len; i++)
{
}
Then for each element, add a new node and move your pointer forward.
curr->next = (Node*) malloc(sizeof(Node));
curr = curr->next;
curr->data = arr[i];
Don't forget to set the last element of your list to point to null! (This can happen outside the for loop.)
n->next = NULL;

Resources