Generic Linked List in C (original) (raw)

Last Updated : 27 Aug, 2024

A generic linked list is a type of linked list that allows the storage of different types of data in a single linked list structure, providing more versatility and reusability in various applications. Unlike C++ and Java, C doesn't directly support generics. However, we can write generic code using a few tricks.

In this article, we will learn how to create a generic linked list in C so that the same linked list code can be worked with different data types.

How to Create a Generic Linked List in C?

In C, we can use a void pointer and a function pointer to implement the generic functionality. The great thing about void pointers is that they can be used to point to any data type. Also, the size of all types of pointers is always the same, so we can always allocate a linked list node. A function pointer along with the size of the data_type is needed to process actual content stored at the address pointed by the void pointer.

Generic Linked List Node Structure

struct Node {
**void *data;
struct Node *next;
};

C Program to Implement Generic Linked List

C `

// C program for implementing a generic linked list #include <stdio.h> #include <stdlib.h> #include <string.h>

struct Node {

// Any data type can be stored in this node
void  *data;
struct Node *next;

};

// Function to insert data at head. This functions requires // the size of the data type as extra argument struct Node* insertAtHead(struct Node* head, void *data, size_t data_size) {

// Allocate memory for node
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

newNode->data = malloc(data_size);
newNode->next = head;

// Copy contents of data to newly allocated memory.
memcpy(newNode->data, data, data_size);

return newNode;

}

// Function that access and prints the linked list. This function needs // to know how many bytes of memory is to be read to print the data // So a function pointer is required for printing different data type void printList(struct Node *head, void (*fptr)(void *)) { while (head != NULL) { (*fptr)(head->data); head = head->next; } }

// Helper function to print an integer void printInt(void *n) { printf(" %d", *(int *)n); }

// Helper function to print a float void printFloat(void *f) { printf(" %f", *(float *)f); }

int main() {

// Create an int linked list
  // 10 -> 20 -> 30 -> 40
  struct Node *head = NULL;
 unsigned i_size = sizeof(int);
 int i_arr[4] = {40, 30, 20, 10};
  head = insertAtHead(head, i_arr, i_size);
  head = insertAtHead(head, i_arr + 1, i_size);
  head = insertAtHead(head, i_arr + 2, i_size);
  head = insertAtHead(head, i_arr + 3, i_size);


  // Printing the Integer list
printf("Created integer linked list is \n");
printList(head, printInt);

// Create an float linked list
  // 10.1 -> 20.2 -> 30.3 -> 40.4
  head = NULL;
 unsigned f_size = sizeof(float);
 float f_arr[4] = {40.4, 30.3, 20.2, 10.1};
  head = insertAtHead(head, f_arr, f_size);
  head = insertAtHead(head, f_arr + 1, f_size);
  head = insertAtHead(head, f_arr + 2, f_size);
  head = insertAtHead(head, f_arr + 3, f_size);


  // Printing the Float list
printf("\n\nCreated float linked list is \n");
printList(head, printFloat);


return 0;

}

`

Output

Created integer linked list is 10 20 30 40

Created float linked list is 10.100000 20.200001 30.299999 40.400002

Time Complexity: O(N), here N is number of nodes in linked list.
**Auxiliary Space: O(N)

Advantages of Generic Linked List

Limitations of Generic Linked List

Conclusion

A generic linked list in C provides a powerful tool for managing collections of various data types. By using void pointers and function pointers, the same linked list implementation can handle different types of data, enhancing flexibility and code reuse. However, it requires careful handling of memory and data types to avoid common pitfalls associated with generic programming in C.