Question regarding multiple singly linked lists - c

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;

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

How to handle the root of a Singly-Linked List

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;

C Linked List with Sentinel - Getting Access to nodes

I'm struggeling to get this task (Implementing a linked list) done. I tried to build a so called sentinel, which sould make it easier. My question is, how do I get access to the actual elements? I tried to print the roots value (44) but I only get weired values. I assume, that these are adresses of memory (e.g. 6893440).
#include<stdio.h>
struct node {
int val;
struct node* next;
};
struct node** init() {
struct node **l;
l = malloc(sizeof(struct node**));
*l = NULL;
return l;
}
void insert(struct node** l, int val) {
struct node* p;
if(*l == NULL) {
p = malloc(sizeof(struct node));
p->val = val;
p->next = *l;
*l = p;
}
}
void main() {
struct node* list;
list = init();
insert(list, 44); // create a (root)node with value 44
printf("%d", list->val); // e.g. 6893440
}
Thank you very much for your help.
You should declare the list as a double pointer to node.
struct node** list;
Then you can access the value of the first node with
(*list)->val
More info:
In the implementation in data types such as lists in C we often use 2 typedefs to help with the readability of the code and eliminate lots of asterisks and ampersands. These are:
typedef struct node* ListNode;
typedef ListNode* List;
By doing this, you can declare a list simply by:
List list;
Note that the implementation of the list functions also becomes more readable by replacing struct node* and struct node** appropriately.

Linked List Definition

This snippet of code is from an assignment I'm working on at school for a data structures module. This bit of code is provided in the question, and I can't understand this.
typedef struct _listnode {
int item;
struct _listnode *next;
} ListNode; // You should not change the definition of ListNode
typedef struct _linkedlist {
int size;
ListNode *head;
} LinkedList; // You should not change the definition of LinkedList
I am confused because my lecture slides and sites I've been to check this out have just defined the node, and not the second one.
Can anyone help me with this please?
LinkedList is a struct denoting a linked list by holding its head and its size, while each node in the list is denoted by struct ListNode. This is a common paradigm if you want to maintain the size of the linked list, in the case you can easily get the number of nodes in the list without have to iterate through it. On the other hand, if size is not concern, you can just use a pointer to node for the head without have to define the LinkedList struct.
So for an empty list, you would have:
LinkedList list = (struct LinkedList){0, NULL};
For a list with one node:
ListNode node;
node.item = 0;
node.next = NULL;
list.head = &node;
list.size = 1;
A linked list is held using a local pointer variable which points to the first item of the list. If that pointer is also NULL, then the list is considered to be empty.
include <stdio.h>
int main() {
typedef struct node {
int val;
struct node * next;
} node_t;
return 0;
}

Wrong memory offset with polymorphic structs

I'm currently implementing a doubly-linked list in C. The purpose of the list is to be as generic as possible. Here's the node struct:
typedef struct list_node
{
struct list_node *prev;
struct list_node *next;
int nodeId;
} Node;
Now, I'm extending this into the following node:
typedef struct history_node
{
Node *node;
String *cmd;
} HistoryNode;
Where the string struct is defined as follows:
typedef struct c_string
{
char *array;
size_t size;
} String;
Now, the problem that I'm having is this: I create a new history node, and set it's string to a value, "hello" for example. I then call on my pushBack function, that is defined as follows:
void pushBack(Node *node, List *list)
{
node->next = list->tail;
node->prev = list->tail->prev;
list->tail->prev->next = node;
list->tail->prev = node;
list->size++;
}
The thing here is that when I assign node->next, instead of accessing the node part of the history node, I access the string, which results in disaster. I have no idea why this is happening. Looking at the addresses in memory, the pointer that is passed in has the correct address, but the address that is accessed in node->next corresponds to the address of cmd and not node. Any ideas?
Just in case, the code that calls this function is:
HistoryNode *node = createHistoryNode(buffer);
pushBack((Node*)node, historyList);
I have already verified that createHistoryNode works as expected, so that is not the source of the problem.
You don't want
typedef struct history_node {
Node *node;
String *cmd;
} HistoryNode;
you want
typedef struct history_node {
Node node;
String *cmd;
} HistoryNode;

Resources