I am trying to print out a table, namely the first ten elements in the periodic table as a linked list with a struct as data. The struct holds the elements' data like so:
typedef struct element{
char *name;
char *symbol;
float weight;
}element;
and then creating the list itself likeso:
typedef struct list{
struct element elements[]; //an array holding element types?
struct list *next;
}list;
so because I need to print out the first 10 elements, I tried using arrays to declare the names, symbols and weights, but I couldn't make the connection of which way to use that in the linked list as data:
char *names[10] = {"Hydrogen", "Helium", "Lithium", "Beryllium", "Boron", "Carbon", "Nitrogen", "Oxygen", "Fluorine", "Neon"};
char *symbols[10] = {"H","He","Li","Be","B","C","N","O","F","Ne"};
float weights[10] = {1.008,4.003,6.941,9.012,10.811,12.011,14.007,15.999,18.998,20.180};
It is unusual for a linked list to have an array of elements, though there are cases where it can be useful. In your case I think a linked list where each list element has one element is more appropriate:
typedef struct list{
struct element element;
struct list *next;
}list;
As a matter of style, we end up with the name element used in the structure name, as the typedef'd name and as a structure member. I suggest to rename them to struct ELEMENT and tElement. The same with the list structure. This will make it like:
typedef struct ELEMENT {
char *name;
char *symbol;
float weight;
} tElement;
typedef struct LIST {
tElement element;
struct LIST *next;
} tList;
I leave it to you to develop the functions to create and add to the list and to print it.
Just add the pointer the the next element. You do not need a new structure for it. Here is some example code (only adding to the list and printing implemented)
There is some code populating the list form the arrays.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct element{
char *name;
char *symbol;
float weight;
struct element *next;
}element;
element *addToList(element *head, const char *name, const char *symbol, float weight)
{
element *current, tmp;
if(!head)
{
head = realloc(head, sizeof(*head));
current = head;
}
else
{
element *wrk;
current = head;
while(current -> next) current = current ->next;
wrk = malloc(sizeof(*head));
if(wrk)
{
current -> next = wrk;
current = wrk;
}
}
if(current)
{
current -> name = malloc(strlen(name) + 1);
current -> symbol = malloc(strlen(symbol) + 1);
//add memory checks here
strcpy(current -> name, name);
strcpy(current -> symbol, symbol);
current -> weight = weight;
current -> next = NULL;
}
return head;
}
size_t printLinst(const element *head)
{
size_t nelems = 0;
while(head)
{
printf("%zu element = {\"%s\", \"%s\", %f}\n", ++nelems, head -> name, head -> symbol, head -> weight);
head = head -> next;
}
return nelems;
}
/* another list functions */
char *names[10] = {"Hydrogen", "Helium", "Lithium", "Beryllium", "Boron", "Carbon", "Nitrogen", "Oxygen", "Fluorine", "Neon"};
char *symbols[10] = {"H","He","Li","Be","B","C","N","O","F","Ne"};
float weights[10] = {1.008,4.003,6.941,9.012,10.811,12.011,14.007,15.999,18.998,20.180};
#define ARRSIZE(arr) (sizeof((arr))/sizeof((arr)[0]))
int main(void)
{
element *head = NULL;
for(size_t index = 0; index < ARRSIZE(weights); index++)
{
head = addToList(head, names[index], symbols[index], weights[index]);
}
printf("List is %zu elements long\n", printLinst(head));
/* another code */
}
https://godbolt.org/z/ddEzTx
You have two main options for linked list structure:
The items contain the links, and so constitute linked list nodes in their own right:
struct element {
char *name;
char *symbol;
float weight;
struct element *next; // <--- here
};
List nodes and data are separate(-ish). For example:
struct element {
char *name;
char *symbol;
float weight;
};
struct node {
struct element *element; // points to the item
struct node *next;
};
or maybe
struct node {
struct element element; // contains the item
struct node *next;
};
There can be a separate structure for the list itself, but there doesn't have to be. The minimal representation of the list is simply a pointer to the head node:
struct node *head;
It is not usual for there to be a structure containing the nodes directly, as you propose, because requiring the nodes to be drawn from such a pool would limit the maximum size of the list. There are other reasons why it can be useful to have a structure type representing the overall list, but that's probably more complexity than you need to worry about for your present task.
Whether you want to declare typedef aliases for your structure types is an entirely separate question, by the way. I rarely do so, myself. It is largely a style question, but I bring it up because some people have the mistaken impression that typedef is an essential element of the definition of a structure type.
When Trying to add a Student to the end of my List it comes out to be in the wrong alphabetical order. I have tried changing the add to end part of my function but can't seem to see what's wrong.
This is the way I add to end
Student *prvPtr= headStudentList;
for(Student *curPtr = headStudentList->next; curPtr != NULL; curPtr = curPtr->next)
{
if (curPtr->next==NULL){
curPtr->next= newPtr; //newPtr
return headStudentList;
}
if(strcmp(curPtr->lastName,last)<0 ){ //change from first
if(strcmp(curPtr->firstName,first)<0 )
{
newPtr->next=curPtr->next;
curPtr->next =newPtr; //curPtr->next =newPtr
return headStudentList; //headStudentList
}
}
}
This is what is inside of the structs
typedef struct _grade {
char name[4];
double value;
struct _grade *next;} Grade;
////////////////////////////////////////////////////////////////////////////////////////
typedef struct _student {
char *lastName;
char *firstName;
Grade *headGradeList;
struct _student *next;} Student;
One thing i see is that you are skipping the first member of your linked list when you initialize your pointer in your for() loop. What if your list is empty? This wont add a node to the end.
I have a struct:
struct person{
char* name;
char* surname;
int age;
};
And I use this struct inside another struct for linked list:
struct listNode {
struct person data;
struct listNode *nextPtr;
};
typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;
I am trying to insert one struct into the linked list. After that I want to get this struct by index and change the age value. In main, I have these codes:
int main() {
ListNodePtr startPtr = NULL;
struct person p;
p.age = 22;
p.surname = "Pilkington";
p.name = "Anthony";
insert(&startPtr, p);
printf("Age1:%d\n", p.age);
struct person p2 = getStruct(&startPtr, 0);
p2.age++;
printf("Age2:%d\n", p2.age);
struct person p3 = getStruct(&startPtr, 0);
printf("Age3:%d\n", p3.age);
return 0;
}
Now, my insert function and getStruct function are working correctly. But I cannot increment the age value. My output is:
Age1:22
Age2:23
Age3:22
I want to make the Age3 23. In insert function, I already allocate memory with malloc, but why can't I change the first value? How can I change this value without removing/adding the node from list?
I search the subject but I cannot find the answer that I want. So, If you can help me I appreciate that.
---EDIT-----
Sorry for not posting getStruct method, I am adding it below:
struct person getStruct(ListNodePtr *sPtr, int index) {
ListNodePtr currentPtr;
struct person c;
int counter = 0;
currentPtr = *sPtr;
while (currentPtr != NULL) {
if (counter == index) {
c = currentPtr->data;
}
counter++;
currentPtr = currentPtr->nextPtr;
}
return c;
}
Here:
struct person p2 = getStruct(&startPtr, 0);
You return a person by value, which is to say you make a copy. Then you modify the copy, not the original. You'll need to do this instead:
struct person *p2 = getStruct(&startPtr, 0);
p2->age++;
printf("Age2:%d\n", p2->age);
That is, return a pointer, which you can use to modify what it points to. This also requires a slight change to getStruct(), whose code you haven't posted.
There are two structures for BST
typedef struct _price {
double price;
char* shopname;
} pricing;
typedef struct _bstnode {
int id;
pricing** pl;
int nr_of_prices;
struct _bstnode *left;
struct _bstnode *right;
struct _bstnode *parent;
} bstnode;
I need to make a function that can add and update price and shop name in BST Node. One Node may contain many shops and prices
void updatePrice(bstnode* root, int id, char* shop, double price){
//to do
}
I can add a single shop name and price but how to add several objects?
(*(root->pl))=malloc(sizeof (pricing)); // ---??
(*(root->pl))->price=price;
(*(root->pl))->shopname=shop;
If nr_of_prices belongs to pl, this will add dynamically one object:
int oldidx = root->nr_of_prices++;
root->pl = realloc( root->pl, root->nr_of_prices * sizeof(*root->pl));
root->pl[oldidx] = malloc(sizeof(pricing));
root->pl[oldidx]->price = price;
root->pl[oldidx]->shopname = shop;
I'm writing a program that solves a maze using DFS algorithm and stack. I was thinking of storing the coordinates of the path used to get to the end onto a struct containing integers x,y for coordinates and then pushing that struct onto a stack to perform other instructions on (print, pop, etc.).
I have searched all over and have yet to find anything that helps. So I went ahead and set it up but I'm getting an error about type compatibility since I have my node data as an int but I'm trying to put in a struct. Being new to linked lists I have only seen data as an int or char. Finally, is it even possible to do what I want? If not could you suggest a way of passing both x,y coordinates onto the stack? Thank you in advance.
Here's a sample of my code, where to save space a1 is an instance of COORD, and list is initialized as well as the maze and such.
typedef struct node {
int data; /* Value or data stored in node*/
struct node *pNext; /* Reference to the next node address */
} NODE;
/*Structure declares pointers for front and back of the list*/
typedef struct LIST {
NODE *front;
NODE *back;
} LIST;
/* Structure to pass multiple values onto stack */
typedef struct COORD{
int x;
int y;
}COORD;
/*Example of one of the functions */
void lst_push_front(LIST *l, COORD *a1) {
NODE *p = malloc(sizeof(NODE));
p->data = a1;
p->pNext = l->front;
l->front = p;
if(l->back == NULL) // was empty, now one elem
l->back = p;
}
Check the code below.
Since COORD is a structure you can include it in another structure as shown in the below code.
Also make sure that the ordering of the structures are proper.
p->data.x is the right way to access the members of the structure COORD
#include <stdio.h>
/* Structure to pass multiple values onto stack */
typedef struct COORD{
int x;
int y;
}COORD;
typedef struct node {
COORD data; /* --> Changes done here */
struct node *pNext; /* Reference to the next node address */
} NODE;
/*Structure declares pointers for front and back of the list*/
typedef struct LIST {
NODE *front;
NODE *back;
} LIST;
void func(COORD *q)
{
NODE *p = malloc(sizeof(NODE));
p->data.x = q->x;
p->data.y = q->y;
printf("%d %d",p->data.x,p->data.y);
free(p);
}
int main(void) {
COORD *q = malloc(sizeof(COORD));
q->x = 20;
q->y = 30;
func(q);
free(q);
return 0;
}
As #barak manos mentions you should put COORD struct before NODE and change int data to COORD data and use p->data = *a1