Pointer to pointer to nested structure - c

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;

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.

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

Linked List, inserting a node in the front

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;

Linked List Help, Singly Linked (Multiple Structures) (C Programming)

I need some help with Linked Lists.
I have figured out how to do individual linked list, but I am struggling when trying to implement multiple struct's and lists.
My last program was all used with Structs but now I must implement linked list's.
It says to use "External Pointers" in the functions to use in traversing through the various lists.
This is homework for one of my classes, I am not asking for you all to do it for me, but I am asking to help point me in the right direction.
The structs are as follows:
struct stockItem
{
char stockName[60];
char stockType[60];
int itemNumber;
float actualCost;
float markUp;
int totalCurrentInventory;
int monthlyRestock;
float price; //stores actual cost + markup
};
struct roomData
{
float widthFeet, widthInch;
float lengthFeet, lengthInch;
char roomName[100];
int roomNumberOfType;
char roomType[6]; //char of room type
int roomStock[100][2]; //for storing each room stock types
int roomHasStock; //if the room has a stock avaliable
int roomStockCount; //how many stocks the room has
float area; // sq ft
float rentalRate;
float profitsPerRoom;
float netProfit;
float grossProfit;
char stockLine[200];
};
struct staffData
{
char firstName[100];
char lastName[100];
char fullName[100];
int employeeNumber;
char typeOfEmployee[10];
char payType[10];
float hourlyWage;
float salary;
int hours;
char address[150];
char city[150];
char state[10];
int zip;
char phone[30];
float yearlyTotalPay;
struct hireDate //holds staff hire date
{
int month;
int day;
int year;
}hireDate;
struct birthDate //holds staff birth date
{
int month;
int day;
int year;
}birthDate;
};
typedef struct YourStructNode_ {
struct YourStructNode_ * next;
struct YourStructNode_ * prev;
YourStruct data;
} T_YourStructList;
Replace "YourStruct" by the name of your structs to make a doubly linked list.
Even if you make more than once T_XXXX_List with this pattern you should manipulate the list with the same function since the two first fields of T_Node is always the same.
Write add, insert, remove functions to manipulate this structure.
Is your linked list supposed to utilize the structs that you have developed? This way you have a linked list where each node contains an instance of all of those structs you listed.
struct node {
struct node *left;
struct node *right;
roomData room;
stockItem stock;
staffData staff;
hireDate hire;
birthDate birth;
};

Resources