Linked List, inserting a node in the front - c

Given an object that holds a linked list, how can I add a new node to the head of that linked list, when I can't return the memory address of that linked list?
struct group {
char *name;
struct user *users;
struct xct *xcts;
struct group *next;
};
struct user {
char *name;
double balance;
struct user *next;
};

It's much simpler than what you think:
usr->next = group->users;
group->users = usr;

Related

how to create a linked list with this struct as data?

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.

Pointer to pointer to nested structure

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;

Printing a struct in a struct in a linked list

I have a struct like this:
typedef struct stockItem {
char *componentType;
char *stockCode;
int numOfItems;
int price;
} stockItem;
// declaration
stockItem *stockItem_new(char *componentType, char *stockCode, int numOfItems, int price);
And a struct like this to store many stock items ( linked list )
typedef struct inventory {
struct stockItem item;
struct inventory *next;
}inventory;
These are both in different header file.
I have created the linked list, I want to print off certain bits of data, such:
void outputData(){
// This temporarily takes the location of the structs in the
// linked list as we cycle through them to the end
struct inventory *myInv = pFirstNode;
printf("Current Inventory\n\n");
// Until the ptr reaches a value of NULL for next we'll
// keep printing out values
while(myInv != NULL){
// HERE IS MY PROBLEM HOW DO I PRINT OFF THE COMPONENTTYPE FROM THIS
printf("%s\n\n", myInv->item->compnentType);
// Switch to the next struct in the list
myInv = myInv->next;
}
}
EDIT:
stockItem *stockItem_new(char *componentType, char *stockCode, int numOfItems, int price){
// creates a new duration for the song
stockItem *item = (stockItem*)malloc(sizeof(stockItem));
// assigns the attributes
item->componentType = componentType;
item->stockCode = stockCode;
item->numOfItems = numOfItems;
item->price = price;
// returns it
return item;
}
We don't see the rest of the code, but since you have stockItem_new returning a pointer, then this is wrong:
typedef struct inventory {
struct stockItem item; ///missing *!
struct inventory *next;
} inventory;
Instead, we need to declare it as:
typedef struct inventory {
struct stockItem *item;
struct inventory *next;
} inventory;
Then you can assign to the item with your stockItem_new function and your outputData will work as you expect.
Update:
In your stockItem_new, you are not making a copy of the contents of componentType, but just pointing to the same value. You either need to allocate a new buffer each time and pass into stockItem_new or take care of that with strdup
item->componentType = strdup(componentType);
This will allocate enough memory and copy the contents of componentType. You would need to do this for any strings you will be keeping in your struct (since only the address is copied!).

BST Links and cases not working

I've a nested struct like this
typedef struct Node_link {
struct Node_base *parent, *left, *right;
}Node_link;
typedef struct Node_base {
struct Node_link link[2];
}Node_base;
typedef struct Node{
struct Node_base base;
int size;
int *address;
}Node;
Node_base *head[2] ={NULL, NULL};
//head[0] stores int size and head[1] it's corresponding address
The node has right, left and parent link, all are nested e.g node->left->link.parent=node. I've to maintain all links(parent, left and right) and delete nodes.
I've tried a lot of cases and still missing some. Can someone tell me what all cases I need to use? Or refer me to some material? I searched a lot but no success.
My insert function is as follows:
Node_base * insert(Node_base *location, Node_base *n) {
if (head[0]==NULL)
head[0]=n;
else
{
if (location==NULL){
location=n;
return location;
}
else{
if(((Node *)n)->size < ((Node *)location)->size){
if(location->link[0].left==NULL)
{
location->link[0].left=n;
location->link[0].left->link[0].parent=location;
}
else
location->link[0].left=insert(location->link[0].left,n);
return location;
}
}
And I've the same nested insert function for head[1] which stores the size of node inserted in head[0].
It's hard to tell what's going on here. Your code doesn't look remotely like any BST implementation I've ever seen. Why the need for the Node_Link struct? The pointers in the Node structs should define what the links are. Why the parent pointer? That shouldn't be needed in a standard BST implementation. All you should need is:
struct node {
node *left;
node *right;
void *data;
int size;
};
struct bst {
node *root;
};

How to free a struct that is inside an other struct

I have the following two structs:
typedef struct label{
int id;
double p,*t,q,c;
int V[45];
struct label *next;
struct label *prev;
struct path *tail;
struct path *head;
}label;
typedef struct path{
int i;
struct path *Pperv;
struct path *Pnext;
}path;
void main (){
int i,j;
struct label *Current,*Head,*Tail;
struct path *test1,*path_head,*path_tail;
Head=(struct label*)malloc(1*sizeof(struct label));
Tail=(struct label*)malloc(1*sizeof(struct label));
Head->next=Tail;
Tail->prev=Head;
for (i=0;i<250000;i++)
{
Current=(struct label*)malloc(1*sizeof(struct label));
Current->t=(double*)malloc(15*sizeof(double));
Current->head=(struct path*)malloc(1*sizeof(struct path));
Current->tail=(struct path*)malloc(1*sizeof(struct path));
Current->head->Pnext=Current->tail;
Current->tail->Pperv=Current->head;
for (j=0;j<15;j++)
{
test1=(struct path*)malloc(1*sizeof(struct path));
test1->Pperv=Current->head;
test1->Pnext=Current->head->Pnext;
Current->head->Pnext->Pperv=test1;
Current->head->Pnext=test1;
test1->i=1;
Current->t[j]=23123.4323334;
}
Current->next=Tail;
Current->prev=Tail->prev;
Tail->prev->next=Current;
Tail->prev=Current;
Current->p=54545.323241321;
}
}
I just used an example of filling some of the variables in them so that I can make my question. What I am facing problem with is how to free the struct "Path" that is contained into the the first struct called name "Label".
I would me sth more than greatful if somenone could give me the code of how to correctly free both structs in C.
In general, you just need to be symmetrical with the calls to malloc/calloc:
label *current = malloc(sizeof(*current));
current->head = malloc(sizeof(*current->head));
...
free(current->head);
free(current);

Resources