Is it a Linked list implementation? - c

I am just learning pointers in C and implemented a singly linked list with 3 elements. Is this the right way of approach. Even if it isn't, does the code which I have written represents a linked list?
#include <stdio.h>
struct node
{
int a;
struct node *link;
};
int main()
{
struct node first;
struct node second;
struct node third;
first.a=1;
first.link=&second;
first.link->a=2;
first.link->link=&third;
first.link->link->a=3;
printf("\n%d",first.a);
printf("\n%d",second.a);
printf("\n%d",third.a);
return 0;
}

The code you have written correctly constructs a singly linked list, but is not a general implementation of a singly linked list data structure. For this, the operations that can be applied to a linked list (for example insert an element at a given position, append an element to the end of the list or count the number of elements in the list) are abstracted out and moved into utility functions.
So, as a next step, try implementing a void append(struct node* head, int value) function that, given a pointer to the head of the list, appends a new node with the given value to the end of the list. Then, try to express the construction of your list using this function.

#include <stdio.h>
struct node
{
int a;
struct node *link;
};
int main()
{
struct node first;
struct node second;
struct node third;
first.a=1;
first.link=&second;
first.link->a = 2;
second.link=&third;
second.link->a=3;
printf("\n%d",first.a);
printf("\n%d",second.a);
printf("\n%d",third.a);
return 0;
}
//the nodes in each struct need to point to the next struct, your code was changing the original destination of first.link from pointing to second and then to third,
it cannot point to both, second contains pointer to third, third would contain pointer to fourth....

Related

How do I delete a doubly linked list in C?

I've created a doubly linked list, filled it with values and now I want to delete it and remove all the values to avoid memory leaks. Here's what I wrote as well as the structs that were used when creating the doubly linked list. Both those functions will be called towards the end of the main function.
struct node
{
struct node *next;
struct node *prev;
char *value;
};
// The type for a list.
typedef struct list
{
struct node head;
} List;
// The type for a list position.
typedef struct list_pos
{
struct node *node;
} ListPos;
void list_destroy(List *lst)
{
List p,q;
p = *lst;
while (p)
{
q = p.head->next;
free(p);
p = q;
}
*lst = NULL;
}
// Remove the value at the position and return the position of the next element.
ListPos list_remove(ListPos pos)
{
}
You appear to have the right general idea: you walk the list and free each node, making sure to grab any needed data from each node (in particular, the pointer to the next node) while the node holding it still exists. Your case differs from some that you might have seen, however, because instead of handling the overall list via a bare pointer to the head node, you have a separate object, of a separate type (List / struct list), to represent the list itself. This approach has much to recommend it, including, especially, the use of (apparently) a dummy head node, which provides for a variety of algorithmic simplifications. This is usually how I write a linked list.
But because struct list is not struct node, you cannot set a list pointer equal to a node pointer. Instead, create a struct node * to track your position. The first node to free would be the one referenced by struct node *to_free = lst->head.next, and the one after that would be the one referenced by to_free->next.
Note that you might need to free the struct list, too.

Create a structure node with unknown number of links

I've worked on linked-lists, Binary trees where we already know the number of links a node can have.
for eg., a doubly linked-list has 2 so as a binary tree.
But when it comes to Graphs, a node can be liked to n number of other nodes, so my question is how do I declare a structure for the node with an unknown number of links.
Binary Tree structure
struct node{
node* left;
node* right;
int data;
}
Singly-linked list
struct node{
node* link;
int data;
}
Here in this graph node "2" has two links, whereas node "4" has three.
I'm new to C, so please bear with my lack of knowledge on these topics, Thanks in advance.
how do I declare a structure for the node with an unknown number of links.
Create a pointer to an dynamically allocated array of pointers to nodes.
struct node {
/// array of pointers to nodes we link to
node **link;
/// count of links
size_t link_cnt;
int data;
};
Then link points to a dynamically allocated array of pointers to nodes - it's an array of "links". The link_cnt can be used to track count of links in the link array.
// example of linking two nodes in one direction.
void node_link_to_node(struct node *this, struct node *other) {
void *p = realloc(this->link, sizeof(*this->link) * (this->link_cnt + 1));
if (p == NULL) abort();
this->link = p;
this->link[this->link_cnt] = other;
this->link_cnt++;
}
I have written this code with C in mind.

How to print linked list node top to bottom

I am trying to make linked list. I can add node one by one but I could not print the linked list as i wanted. How to print linked list node from top to bottom
#include<stdio.h>
#include<stdlib.h>
struct node{
int N;
struct node *next;
};
struct node* newNode(int number, struct node *next) {
struct node *new = malloc(sizeof(*new));
new->N = number;
new->next = next;
return new;
}
void show(struct node *head){
struct node *c;
c = head;
while (c!=NULL){
printf("%d\n",c->N);
c = c->next;
}
}
int main (void ) {
struct node *head = NULL;
head = newNode(10, head);
head = newNode(20, head);
head = newNode(30, head);
head = newNode(40, head);
show(head);
return 0;
}
Output
40
30
20
10
I am trying to print node like below
10
20
30
40
How to get above output ?
Since I understand this is probably part of an excercise, I will attempt to answer it in the style of assistance, while still giving a comprehensive answer.
I let aside the fact that you insert your elements in the head - which I am not sure it is what you want to do, and I consider the question as "How to print it backwards, once I have entered the elements correctly?".
We have to examine possible solutions on this:
1) Create a method void addToTail(Node* head, int value); That traverses the list and adds elements to the tail of the list instead of the head. Side note: this operation is time costly, as it requires O(N) time complexity. About complexities, read more here. Se also this StackOverflow question.
2) You mention the term "linked list". By what you say, you do not specify if it is a singly linked, or a doubly linked. And since you have access to the node implementation, I suggest that you add a pointer to each node that points to the previous element, thus converting your singly-linked list to a doubly-linked one.
struct node{
int N;
struct node *next;
struct node *prev;
};
And, of course, you need to update this node respectively in the operations of your list - otherwise it will not work - I let this to you.
That way, you will be able to easily iterate the list backwards then in order to print the number in the order desired.
3) You could implement a function Node * reverseList(Node* head); that "reverses" a list via iteration, and then use it to print the list reversed.
And again, I let the implementation to you. Of, course, you need to consider the list state on each time, as also if you need to reverse the list in-place or return a pointer to a new, reversed list (as the function contract above indicates).
What you need to do now, is re-read your excercise brief, stop for a moment and think: "Do I really need these solutions? Is this what is requested from me?".
If you are just entering the data in the wrong order, probably not.
But if it is specifically required from you to print the list elements backwards, then you have some good hints on how to proceed.
Recursive approach works great here:
void show(struct node *c){
if (c == NULL)
return;
show(c->next);
printf("%d\n", c->N);
}

C: Linked LIst and Pointer to Pointer

The struct that will represent the node of the linked list:
typedef struct node{
int val;
struct node *next;
} node_t;
and the head of our list:
node_t *head;
Now, I wanna build a function that creates the first element in the list, of course that will be pointed by *head. I am gonna start with the correct version, in my point of view, of the function, where I used a pointer who points to head, namely a double pointer:
void createFirstElement(node_t **head, int value){
*head=NULL;
*head=malloc(sizeof(node_t));
(*head)->val=value;
(*head)->next=NULL;
}
When I used that version of createFirstElement I got the value of the node printed. However I have a question for my first version of createFirstElement which didn't worked:
void createFirstElement(node_t *head, int value){
head=NULL;
head=malloc(sizeof(node_t));
head->val=value;
head->next=NULL;
}
How is this version different from the one with double pointers? I am still getting the head pointer in parameter (instead of a pointer that points to head) and make all the changes inside.
Thanks everyone in advance!
C uses "call by value", so in the second version you are working with a copy of node_t *head. When the function returns, the head which was passed to the function remains unchanged.

Trying to create an empty linked list in C

I'm trying to create an empty linked list, which asks the user for the maximum number of terms that the list can hold. (I didn't add my code for that as its simply a printf). I then have to create a new function which asks the user to insert input into the previously created list.
My question is, how do I make the create_q() function return the empty list?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node_t {
int value;
int priority;
struct node_t *next;
}node;
typedef struct priority_linked_list {
struct name *head;
int current_size;
int max_size;
}priority_list;
typedef node *Node;
typedef priority_list *List;
void create_q(int max_terms) {
node *head = NULL;
node *next = NULL;
List *current_size = 0;
List *max_size = max_terms;
}
In C, linked lists are usually implemented as a series of nodes stored on the heap that point to eachother. The heap is a persistent memory area that runs throughout the life-cycle of the program.
When you create a variable normally in a C function, and the function returns, the variable that you created is no longer accessible. However when you create something on the heap in a function, and the function is returned, the data you allocated on the heap is still there. However, you have no way of accessing it-- unless the function returns a pointer.
So what you would do for create_q() would be to create the linked list on the heap (using a function in stdlib.h called "malloc"), and then you would return a pointer to your first node, letting the main function know where on the heap to find the first node. Then that first node would have a pointer in it, telling the program where on the heap to find the second node, and so forth.
However, you're probably approaching linked lists the wrong way. Unless this is for some sort of homework project, you probably wouldn't want to create an empty linked list. One of the benefits of a linked list is that it's a dynamic structure in which you can easily insert new nodes. You could still have some variable keeping track of the maximum size you want the list to be, but you probably wouldn't want to actually create the nodes until you had to.
Just keep in mind what a linked list is. It's a set of nodes floating on the heap (in C) that each store some data, and contain a pointer to the next node floating on the heap. All you need, to access the linked list, is a pointer to the first node. To add a new node, you simply "walk" through the list till you reach the last node, and then create a new node and have the old-last node point to it.
Is this what you had in mind?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node_t
{
int value;
int priority;
struct node_t *next;
};
static int current_size;
static int max_size;
static struct node_t* head = NULL;
struct node_t* create_q(int);
struct node_t* create_q(int max_terms)
{
int i; // loop counter/index
current_size = max_terms;
max_size = max_terms;
if( NULL == (head = malloc(sizeof(struct node_t)*max_terms)))
{ // then, malloc failed
perror("malloc failed for struct node_t list");
exit( EXIT_FAILURE );
}
// implied else, malloc successful
// set all fields to '0,0,Null'
memset( head, 0x00, sizeof(struct node_t)*max_terms);
// set all next links, except last link
for(i=0;i<(max_terms-1);i++)
{
head[i].next = &head[i+1];
}
// set last link
head[i].next = NULL;
return( head );
} // end function: create_q
I suspect you are looking for something like the following for creating or initializing your priority linked list.
/*****
* alloc_q - allocate memory for the priority linked list
*/
struct priority_linked_list *alloc_q(void)
{
struct priority_linked_list *list;
list = malloc(sizeof(*list));
return list;
}
/******
* init_q - initialize the priority linked list
*/
void init_q(struct priority_linked_list *list, int max_terms)
{
list->head = NULL;
list->current_size = 0;
list->max_size = max_terms;
}
/******
* create_q - allocate AND initialize the priority linked list
*/
struct priority_linked_list *create_q(int max_terms)
{
struct priority_linked_list *list;
list = alloc_q();
if (list == NULL) {
return NULL;
}
init_q(list, max_terms);
return list;
}
Allocation of nodes and their addition/removal to/from the list would be handled separately.
There may be typos in the above (I have not tested it). However, it should be enough to get you on the path you want.
Hope it helps.

Resources