How to handle the root of a Singly-Linked List - c

Let's say I have a node in a Linked List defined as follows:
struct movie {
char title[50];
int year;
};
// so we can swap in other types by changing the `typedef Item`
typedef struct movie Item;
struct node {
Item item;
struct node *next;
};
How is the head/root of the list usually handled? Is this as simple as just doing:
struct node *head;
Or is the LinkedList usually handled as a wrapper struct, something like:
struct LinkedList_ {
struct node* head;
size_t size;
// anything else?
} LinkedList;
And we just use the LinkedList and add functions around that item? For example: LinkedList->addNode(...).

There really is no right and wrong here. This is more of a design decision, than anything else. For me personaly, I usually don't use any kind of wrapper, nor do I store the size, since the end of the list is marked by a null pointer. So to iterate it I usually use something like this:
for(struct node *current = first; current != NULL; current = current->next);
I also store both the head and the tail. So You can easily add nodes to the list.
struct node *newNode = (struct node *)malloc(sizeof(struct node));
newNode->next = NULL;
tail->next = newNode;
tail = newNode;

Related

How to initialize this NodeList class in C

I'm pretty newbie in C language and I have this little code in which I want to do some test in the main code.
struct ListNode
{
int val;
struct ListNode *next;
};
I want to create some examples (For example: 4 -> 9 -> 1) in the main code, but I don't really know how to initialize them. Thank you in advance.
I would do something like this:
struct ListNode* addnode(struct ListNode *head,int val)
{
struct ListNode* newnode = malloc(sizeof(*this));
newnode->val = val;
newnode->next = NULL;
if (!head) head = newnode;
else {
struct ListNode *this = head;
while(this->next)
this = this->next;
this->next = newnode;
}
return head;
}
int main(void)
{
struct ListNode *head = NULL;
head = addnode(head,4);
addnode(head,9);
addnode(head,1);
return 0;
}
Using this structure you need in main at first to declare a pointer to the head node of the list and initialize it as a null pointer. For example
struct ListNode *head = NULL;
Then you need to write a function that will store values in the list by dynamically allocating nodes that will be added to the list. Or you could create dynamically nodes in a loop if you a going to do all the functionality in main.
Pay attention to that if you have a singly-linked list then it is more efficient to add new nodes to the beginning of the list. Or if you want to add new nodes to the tail of the list then you should declare a two-sided singly-linked list like for example
struct ListNode
{
int val;
struct ListNode *next;
};
struct List
{
struct ListNode *head;
struct ListNode *tail;
};
In this case declaration of the list in main can look like
struct List list = { .head = NULL, .tail = NULL };

I need help returning the next node of a doubly linked list in C

I created a doubly linked list and in the function that adds values to the list, it calls the function list_next which is supposed to return the next node in the list but I'm unable to figure out just how to do that. I feel like ListPos Pos is a double pointer hence why I wrote my code like that, but it's apparently wrong. How should I go about writing it and how would I avoid that mistake in the future?
struct node
{
struct node *next;
struct node *prev;
char *value;
};
typedef struct list_pos
{
struct node *node;
} ListPos;
ListPos list_next(ListPos pos)
{
return &(*pos.node)->next;
}
Here's your code with some changes, explained in comments, which hopefully will help you:
struct node
{
struct node *next;
struct node *prev;
char *value;
};
// typedefs are more confusing than they are useful
struct list_pos
{
struct node *node;
};
struct list_pos list_next(struct list_pos pos)
{
// don't be afraid to use temp variables to make your code clearer
struct node *current = pos.node;
assert(current != NULL); // one way to indicate assumption
// you could also check if current is NULL and return NULL in that case
struct node *next = current->next;
return (struct list_pos){next}; // compound literal to avoid temp variable
}
&(*pos.node)->next doesn't make any sense.
You probably want this:
ListPos list_next(ListPos pos)
{
ListPos next;
next.node = pos.node->next;
return next;
}
What Jabberwocky suggested is the right answer. I just wanted to add that you could replace
typedef struct list_pos
{
struct node *node;
} ListPos;
with
typedef struct node* ListPos;
because you looked like you were thinking that ListPos is a pointer rather than separate struct.

Question regarding multiple singly linked lists

I'm trying to create multiple singly linked lists by using a list struct and a node struct. What I am thinking is each new list is told apart by a different head. But what makes me confused is how do I initialize a new head for each list and then add on nodes?
When I worked with just one list I was able to just allocate memory for the one head pointer and set it to NULL and then just add on new nodes.
My structs looks like this for reference:
typedef struct node
{
int value;
struct node *next;
}node_t;
typedef struct list
{
struct list *head;
int size;
}list_t;
If you feel like I've been unclear on something just ask and I will clarify!
Thanks
In your list structure head should actually be a node_t - first node in the list.
And then you will chain the nodes by assigning another node_t to next
typedef struct node
{
int value;
struct node *next;
}node_t;
typedef struct list
{
node_t *head;
int size;
}list_t;
Simple example for reference:
node_t node1;
node_t node2;
node1.value = 1;
node1.next = &node2;
node2.value = 1;
node2.next = NULL;
list_t list;
list.head = &node1;
list.size = 2;
After re-reading your question multiple times, I probably finally understand what you are trying to achieve. You want list_t to contain multiple "lists" of type node_t.Then you need to make head an array of node_t pointers like this:
typedef struct node
{
int value;
struct node *next;
}node_t;
typedef struct list
{
node_t *head[2];
int size;
}list_t;
(i've used array of static size of 2 for simplicity. If you want to make it dynamic, you will need to take care of memory allocations on your own)
And example code:
// list1
node_t node11;
node_t node12;
node11.value = 1;
node11.next = &node12;
node12.value = 1;
node12.next = NULL;
//list2
node_t node21;
node_t node22;
node11.value = 2;
node11.next = &node22;
node12.value = 2;
node12.next = NULL;
list_t list;
list.head[0] = &node11;
list.head[1] = &node21;
list.size = 2;

Creating lists of lists (Structs)

I am doing a programming assignment at the moment and I dont really have a full grasp of linking as we havent covered it yet. However I feel I need it to do what I want as arrays are not sufficent
I have created a struct as follows
struct node
{
float coef;
int expo;
struct node *link;
};
from this I can create pointers to the struct each with different names, however the problem I encountered is that I want user input to determine the amount I structs. I also want the ability to add and create the different structs.
You need to create a head pointer to keep track of your list.
This might be helpful:
struct list
{
struct node *head;
int count;
};
And you need to allocate memory for each new node and move the head to the newly created one.
struct node *add_node(struct list *pList, float coef, int expo)
{
if (pList == NULL)
{
return NULL;
}
struct *node pNode = (struct node*)malloc(sizeof(struct node));
if (node == NULL)
{
return NULL;
}
pNode->coef = coef;
pNode->expo = expo;
pNode->link = pList->head;
pList->head = pNode;
pList->count++;
return pNode;
}
To delete an element you need to move the head forward and then free it previous memory.
void *delete_node(struct list *pList, float coef, int expo)
{
if (pList == NULL)
{
return NULL;
}
struct node *tmp = pList->head;
pList->head = pList->head->link;
free(tmp);
pList->count--;
}
Note:
This is not the ultimate version. I'm just pointing my fingers to what should be done.
I would try something like this as your data structure
struct node
{
float coef;
int expo;
struct node *link;
};
struct poly
{
node *value;
struct poly *link
}
Maintain a linked list of polys, each of which contains a linked list of nodes.

Assignment from incompatible pointer type in C

I keep getting an "Assignment from incompatible pointer type" and I can't figure out why. I thought it looked right. I'm just trying to do the basics of a linked list in C.
typedef struct{
int id;
struct node *next;
} node;
node *root = NULL; // Sets up a root node when the program starts.
create nodes(int id){
if(root == NULL){
root = (node*)malloc(sizeof(node));
root-> id = -1;
node *nextNode;
nextNode = (node*)malloc(sizeof(node));
nextNode -> id = id;
root-> next = nextNode; // This line is throwing an error.
}
}
I feel like it's something simple but I can't put my finger on it...
Your struct is actually an unnamed struct typedef-d to node, but you're trying to refer to it as struct node later (which is not the same as your node typedef). Quick fix is to simply give the struct a name:
typedef struct node {
int id;
struct node *next;
} node;
Or, if you prefer (and this is completely stylistic), remove the typedef and correct your other references to the struct:
struct node {
int id;
struct node *next;
};
struct node *root = NULL;
create nodes(int id){
if(root == NULL){
root = malloc(sizeof(struct node));
root->id = -1;
struct node *nextNode;
nextNode = malloc(sizeof(struct node));
nextNode->id = id;
root->next = nextNode;
}
}
Four points here:
First. Add a name of the struct node, if you must include pointer in the field of the struct (as #JamesMcLaughlin pointed out above). For example:
typedef struct nodetag {
int id;
struct nodetag *next;
} node;
Second. Make sure you are using the variable type create as intended. I assume user-defined variable type create exist within your #define or somewhere else. If not, this will cause a compiler error. Even if you did, this won't compile as you don't have a return statement that returns create.
Third. Include node *root = NULL; within your function nodes. Otherwise, function nodes won't recognize the variable root and results in a compiler error.
Fourth. Declare local variables in the beginning of the function. The line struct node *nextNode; will cause a compiler error for C89 as C89 does not allow type-declaration after statements. C99, however, allows such practice. It's advised to declare all of the local variables in the beginning of the function to be compatible with both C89 and C99.
Try this
struct node{
int id;
struct node *next;
} ;
struct node *root = NULL; // Sets up a root node when the program starts.
/* Return type is missing in your code*/ create_nodes(int id){
if(root == NULL){
root = (struct node*)malloc(sizeof(struct node));
root-> id = -1;
struct node *nextNode;
nextNode = (struct node*)malloc(sizeof(struct node));
nextNode -> id = id;
root-> next = nextNode; // This line is throwing an error.
}
}

Resources