Linked List Insertion Simple - c

#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int key;
struct node* next;
} node_t;
typedef node_t* node_ptr;
void main()
{
node_ptr p = NULL;
node_ptr listhead =NULL;
/*need to create a listhead with key = 1,2,3..10*/
int i;
for (i =1; i<= 10;i ++)
{
node_ptr temp;
p =(node_ptr)malloc(sizeof(node_t));
p->key = i;
p->next = NULL;
if( list_head == NULL )
{
list_head= p;
}
else
{
temp = listhead;
while(temp->next != NULL)
{
temp = temp->next;
}
temp->next = p;
}
}
}
I am still pretty confused about linked list and I am not sure if I'm doing correctly and pretty sure it is wrong, could anyone help me out? This is just
a practice question :)
And also uptil the line of node_ptr listhead=NULL; is given in the question so i cannot change the stuffs above that.
By the way just to be clear, the question asks to insert keys 1,2,3..10 to the listhead.

"Insert" can imply inserting at the start of a list rather than at some point in the list or at the end of a list. For this assignment, what is "insert" supposed to mean?
Example code with for loop and minor changes like using node_ptr instead of node_t * to correspond with assignment typedef, and int main() instead of void main().
#include <stdlib.h>
typedef struct node{
int key;
struct node* next;
} node_t;
typedef node_t* node_ptr;
int main()
{
node_ptr list_head = NULL;
node_ptr p;
node_ptr temp;
int i;
/* create a list with keys = 1,2,3..10 */
for (i = 1; i <= 10; i++)
{
p = (node_ptr)malloc(sizeof(node_t));
p->key = i;
p->next = NULL;
if( list_head == NULL )
{
list_head= p;
}
else
{
for(temp = list_head; temp->next != NULL; temp = temp->next);
temp->next = p;
}
}
return 0;
}
Alternate version using pointer to pointer to node. This eliminates the initial check for list_head == NULL. It's beyond what you'd be using now for the assignment, but knowing how to do this could be useful in later assignments.
#include <stdlib.h>
typedef struct node{
int key;
struct node* next;
} node_t;
typedef node_t* node_ptr;
typedef node_t ** node_ptr_ptr;
int main()
{
node_ptr list_head = NULL;
node_ptr p;
/* ptr to either list_head or to last node.next */
node_ptr_ptr pptemp;
int i;
/* create a list with keys = 1,2,3..10 */
for (i = 1; i <= 10; i++)
{
p = (node_ptr)malloc(sizeof(node_t));
p->key = i;
p->next = NULL;
for(pptemp = &list_head; *pptemp != NULL; pptemp = &(*pptemp)->next);
*pptemp = p;
}
return 0;
}
For this particular case, since temp (or pptemp) is in main, it only needs to be initialized once and advanced once per loop:
#include <stdlib.h>
typedef struct node{
int key;
struct node* next;
} node_t;
typedef node_t* node_ptr;
typedef node_t ** node_ptr_ptr;
int main()
{
node_ptr list_head = NULL;
node_ptr p;
/* ptr to either list_head or to last node.next */
node_ptr_ptr pptemp = &list_head;
int i;
/* create a list with keys = 1,2,3..10 */
for (i = 1; i <= 10; i++)
{
p = (node_ptr)malloc(sizeof(node_t));
p->key = i;
p->next = NULL;
*pptemp = p;
pptemp = &p->next;
}
return 0;
}

Related

How to loop over a linked-list in 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.

Doubly linked list not working

I am trying to sort a doubly linked list in ascending order. I've gone trough the code again and again, and I can't find any logical flaws with it, so I assume the problem is elsewhere. When I try to print the sorted list, the console returns 0 without printing anything (the print function is not to blame, since it has already been tested)
Here is the code I am currrently running:
typedef struct dados_temp{
float temp;
float incerteza;
char pais[100];
char cidade[100];
float angle;
int hemisferio;
int dia;
int mes;
int ano;
} dados_temp;
typedef struct Node{
dados_temp payload;
struct Node *next;
struct Node *prev;
} Node;
//receives the original head pointer
//returns sorted list's head pointer
Node** SortDate(struct Node** head)
{
struct Node *i, *j;
for( i = head; i != NULL; i = i->next )//iterates over the entire list
{
//if the data value of the next node is bigger
if ( i->payload.ano > i->next->payload.ano )
{
//swaps the data value between i and i->next
//SwapNodes was tested and it is working
SwapNodes(i, i->next);
//the current value of i->next (former value of i)
//is compared to all the previous values
//and keeps swapping until a smaller value is found
for (j = i->next; j->payload.ano < j->prev->payload.ano;)
{
SwapNodes(j, j->prev);
}
}
}
return head;
}//sort
I know there probably are easier ways to sort doubly linked list, but I'm trying to figure out why this one doesn't work.
Thank you in advance!
EDIT:
showing all the involved functions:
#include <stdio.h>
#include <stdlib.h>
typedef struct dados_temp{
float temp;
float incerteza;
char pais[100];
char cidade[100];
float angle;
int hemisferio;
int dia;
int mes;
int ano;
} dados_temp;
typedef struct Node{
dados_temp payload;
struct Node *next;
struct Node *prev;
} Node;
Node * CreateCitiesList();
Node * CreateCountriesList();
Node * Intervalos(struct Node*, int[]);
void PrintBack(struct Node*);
struct Node* CreateNode (dados_temp x)
{
struct Node* NewNode = (struct Node*)malloc(sizeof(struct Node));
NewNode->payload = x;
NewNode->next = NULL;
NewNode->prev = NULL;
return NewNode;
}
}
void Print (struct Node* head)
{
struct Node* temp = head;
while ( temp != NULL)
{
printf("%d-%d-%d \n", temp->payload.ano, temp->payload.mes,
temp>payload.dia);
fflush(stdout);
temp = temp->next;
}
printf("\n");
}
Node* SortDate (struct Node*);
void SwapNodes (struct Node*, struct Node*);
int main(int argc, char* argv[])
{
CreateCountriesList();
}
Node* CreateCountriesList()
{
char linha[150] = {NULL};
char cabecalho[100] = {NULL};
int i = 0;
dados_temp New_Entry;
dados_temp tail;
int *ptr_head_co;
struct Node* head_countries = NULL;
struct Node* Node = NULL;
FILE *inputf;
inputf = fopen("tempcountries_all.csv", "r");
if (inputf == NULL)
{
printf("Nao da pa abrir o fitchas boi");
exit(EXIT_FAILURE);
}
//gets rid of the first line
fgets(cabecalho, 100, inputf);
for (i = 0; i < 577462 ; i++)
{
fgets(linha, 150, inputf);
//scans the date(amongst other things) from file (yyyy-mm-dd)
sscanf(linha, "%d-%d-%d,%f,%f,%[^,]s", &New_Entry.ano,
&New_Entry.mes,&New_Entry.dia, &New_Entry.temp, &New_Entry.incerteza,
&New_Entry.pais);
if (head_countries == NULL)
{
head_countries = CreateNode(New_Entry);
Node = CreateNode(New_Entry);
}
else
{
head_countries = InsertHead(head_countries, New_Entry);
}
}
fclose(inputf);
head_countries = RemoveNodes(Node);
SortDate(head_countries);
Print(head_countries);
return head_countries;
}
Node* SortDate(struct Node* head)
{
struct Node *i, *j;
for( i = head; i != NULL; i = i->next )
{
if ( i->payload.ano > i->next->payload.ano )
{
SwapNodes(i, i->next);
for (j = i->next; j->payload.ano < j->prev->payload.ano;)
{
SwapNodes(j, j->prev);
}
}
}
}//sort
void SwapNodes(struct Node* node1, struct Node* node2)
{
dados_temp temp = node1->payload;
node1->payload = node2->payload;
node2->payload = temp;
}

error in function that counts the number of times an int appears in a list

I'm trying to count the number of times a given int occurs in a list, but I'm having a difficult time getting my pointers to work. Can someone spot where is my logic failing? Is it because of how I'm implementing the "follows" "->" in the counting function?
//this is in my .h file
typedef struct list_struct LIST;
///// the rest is in my .c file
typedef struct node {
ElemType val;
struct node *next;
} NODE;
struct list_struct {
NODE *front;
NODE *back;
};
//this is my counting function
int lst_count(LIST *l, ElemType x) {
LIST *current = l;
int count = 0;
while (current != NULL) {
if ((current->front->val) == x) count++;
current = current->front->next;
//in the line above I get the following warning:
//"incompatible pointer types assigning to 'LIST*' (aka 'struct list_struct*') from 'struct node*'"
}
return count;
}
Your problem is in the while loop
You are in a list struct, then you do
current->front->next;
Now you are in a NODE type struct, in the next iteration there is no front in NODE.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node *next;
struct node *previous;
} NODE;
int lst_count(NODE *l, int x) {
NODE *current = l;
NODE *start = current; /* so that we wont loose the start*/
int count = 0;
while (current != NULL) {
if ((current->val) == x)
count++;
current = current->next;
}
return count;
}
int main()
{
NODE* p = (NODE*)malloc(sizeof(NODE));
NODE* p1 = (NODE*)malloc(sizeof(NODE));
NODE* p2 = (NODE*)malloc(sizeof(NODE));
NODE* start = p;
p->val = 5;
p->next = p1;
p1->next = p2;
p2->next=NULL;
p1->val = 5;
p2->val = 5;
printf("%d", lst_count(start, 5));
}
I got the function to work thanks to your all advises
int lst_count(LIST *l, int x) {
NODE *current = l->front;
int count = 0;
while (current != NULL) {
if ((current->val) == x) count++;
current = current->next;
}
return count;
}

Using a for loop to create a linked list [duplicate]

This question already has answers here:
Creating a linked list with a for loop
(2 answers)
Closed 9 years ago.
Newb C programmer here, assuming I have a struct for a node as follows
struct node{
int data;
struct node *next;
};
How would I use a loop to make a linked list where the first node's data is 0, and a pointer to the next node whose data is 1. etc.
EDIT:
int main(int argc, char* argv[]){
struct node a;
a.data = 0;
struct node * tempnode = &a;
for (int i = 1; i < 5; i++){
struct node * next;
next->data = i;
tempnode->next = next;
tempnode = next;
}
Heres what i tried but it doesn't work
This might help..
#include<stdio.h>
#include<stdlib.h>
// Prototypes
void InitList(struct list *sList);
void push(struct list *sList, int data);
void pop(struct list *sList);
void print(struct list *sList);
/* Node Structure */
struct node {
int data;
struct node *next;
};
/* List Structure */
struct list {
struct node *start;
};
int main(int argc, char** argv)
{
int x;
struct list MyList;
InitList(&MyList);
for(x = 0; x < 100; x++) push(&MyList, x);
print(&MyList);
printf("\n");
for(x = 0; x < 25; x++) pop(&MyList);
print(&MyList);
printf("\n");
for(x = 0; x < 80; x++) pop(&MyList);
print(&MyList);
printf("\n");
return 0;
}
/* Initializes the list structure */
void InitList(struct list *sList)
{
sList->start = NULL;
}
/* Adds a value to the front of the list */
void push(struct list *sList, int data)
{
struct node *p;
p = malloc(sizeof(struct node));
p->data = data;
p->next = sList->start;
sList->start = p;
}
/* Prints the list */
void print(struct list *sList)
{
struct node *p = sList->start;
while(p != NULL) {
printf("%d ", p->data);
p = p->next;
}
}
/* Removes the first value of the list */
void pop(struct list *sList)
{
if(sList->start != NULL) {
struct node *p = sList->start;
sList->start = sList->start->next;
free(p);
}
}
You are not allocating memory to store your struct data. Here's how you can do it
for(int i = 1; i < 5; i++) {
struct node *next = malloc(sizeof *next); // allocate memory to store the struct
next->data = i;
tempnode->next = next;
tempnode = next;
}

C linked list push function, just checking if this is correct

So I'm just wondering if this push function, which pushes a new value to the top a linked list stack is correct
void push(node** hd, int v){
node temp;
temp = (node*)malloc(sizeof(node));
temp -> val = v;
temp -> next = *hd;
*hd = temp;
}
Thanks in advance!
Also I'm wondering how I would make a pop function, to pop the most recently pushed value off of the stack.
The struct code looks like this by the way...
typedef struct nodeStruct
{
int val;
struct nodeStruct* next;
}node;
typedef node* list;
Dont define pointer types. They are confusing. Define a normal type and dereference it explicitly. Here is what you were trying to do without the pointer types.
#include <stdlib.h>
#include <stdio.h>
typedef struct nodeStruct
{
int val;
struct nodeStruct *next;
} node;
static void push(node **head, int v)
{
node *temp = malloc(sizeof(node));
temp->val = v;
temp->next = *head;
*head = temp;
}
int main(int argc, char **argv)
{
(void) argv;
(void) argc;
node *list = NULL;
for (int i=0; i<10; ++i) {
push(&list, i);
}
for(node *l = list; l != NULL; l = l->next) {
printf("%d ", l->val);
}
printf("\n");
return 0;
}
Note that you should check for failure of malloc. In other words, malloc can return NULL, which should be handled - left to you.

Resources