Singly Linked List Implementation
In this post, you will see the implementation of a singly linked list. It is one of the main data structures in computer programming.
A singly linked list consists of nodes which are bound to each other with their "next" pointers.
A simple node is represented at least 2 fields. A "next" node pointer and a "data" field.
Some of the basic methods of a linked list and node data structures are implemented below.
Create a Node Method:
List Length Get Method:
Add Head Method with Data:
Add Tail Method with Data:
Remove Node by Data:
Reverse List:
Look Up a Data in the List:
Print List:
Test Code:
Test Output:
Creating link list
Source Download:
https://github.com/sezginmurat/list_lib.git
A singly linked list consists of nodes which are bound to each other with their "next" pointers.
A simple node is represented at least 2 fields. A "next" node pointer and a "data" field.
/*
* node structure.
*/
struct node {
struct node *next;
int data;
};
Some of the basic methods of a linked list and node data structures are implemented below.
Create a Node Method:
/*
* node_create()
* Creates a node.
*/
struct node *node_create(int data)
{
struct node *n = malloc(sizeof(struct node));
if (!n) {
printf("Unable to allocate memory for node\n");
return NULL;
}
n->data = data;
n->next = NULL;
return n;
}
Free a Node Method:
/*
* node_free()
* Frees a node.
*/
void node_free(struct node *n)
{
if (!n) {
return;
}
free(n);
}
/*
* list_lenght_get()
* Gets the length of a list.
*/
int list_lenght_get(struct node *list)
{
int count = 0;
while (list) {
count++;
list = list->next;
}
return count;
}
/*
* list_add_data_head()
* Adds a node by data to the head of the linked list.
*/
void list_add_data_head(struct node **list, int data)
{
struct node *n = (struct node *)malloc(sizeof(struct node));
if (!n) {
printf("Unable to allocate memory for node\n");
return;
}
n->data = data;
n->next = *list;
*list = n;
}
/*
* list_add_data_tail()
* Adds a node by data to the tail of the linked list.
*/
void list_add_data_tail(struct node **list, int data)
{
struct node *nd = (struct node *)malloc(sizeof(struct node));
if (!nd) {
printf("Unable to allocate memory for node\n");
return;
}
nd->data = data;
nd->next = NULL;
if (!(*list)) {
*list = nd;
return;
}
struct node *n = *list;
while(n->next) {
n = n->next;
}
n->next = nd;
}
Add a Node to Tail Method:
/*
* list_add_node_tail()
* Adds an allocated node to a linled list tail.
*/
void list_add_node_tail(struct node **list, struct node *n)
{
struct node *curr = *list;
if (!*list) {
*list = n;
return;
}
while (curr->next) {
curr = curr->next;
}
curr->next = n;
}
/*
* list_remove_node_by_data()
* Remove a node by data from linked list.
*/
void list_remove_node_by_data(struct node **list, int data)
{
/*
* If list is empty, just return.
*/
if (!*list) {
printf("list is empty\n");
return;
}
/*
* curr is our list head.
*/
struct node *curr = *list;
struct node *tmp;
/*
* If there is multiple occurences at the head of the list,
* remove all of them.
* 1->1->1->5->6->null
*/
while (curr && (curr->data == data)) {
tmp = curr;
*list = curr->next;
curr = *list;
free(tmp);
}
/*
* Check the list. Did we remove all the nodes?
*/
if (!*list) {
printf("list is empty. All the occurences removed from the head\n");
return;
}
/*
* There are more nodes in the list. Check them as well.
* If we find more occurence, prev->next will be bound to curr->next.
*/
struct node *prev = curr;
curr = curr->next;
while (curr) {
if (curr->data == data) {
tmp = curr;
prev->next = curr->next;
curr = curr->next;
free(tmp);
continue;
}
prev = curr;
curr = curr->next;
}
}
/*
* list_reverse()
* Reverses a linked list.
*/
void list_reverse(struct node **list)
{
struct node *prev = NULL;
struct node *curr = *list;
struct node *next_node = *list;
/*
* If list is empty, just return.
*/
if (!*list) {
printf("list is empty\n");
return;
}
while (curr) {
next_node = curr->next;
curr->next = prev;
prev = curr;
curr = next_node;
}
*list = prev;
}
/*
* list_data_look_up()
* Look ups a node by a data inside the linked list.
*/
bool list_data_look_up(struct node *list, int data)
{
while (list) {
if (list->data == data) {
return true;
}
list = list->next;
}
return false;
}
Print List:
/*
* list_print()
* Prints linked list.
*/
void list_print(struct node *list)
{
if (!list) {
printf("list is empty, cannot print\n");
return;
}
struct node *n = list;
while (n) {
printf("%d->", n->data);
n = n->next;
}
printf("NULL\n");
}
Test Code:
/*
* Global list object.
*/
struct node *list = NULL;
/*
* Test Code.
*/
int main(void)
{
printf("Creating link list\n");
list_add_data_head(&list, 1);
list_add_data_head(&list, 1);
list_add_data_tail(&list, 5);
list_add_data_tail(&list, 6);
list_add_data_tail(&list, 1);
list_add_data_tail(&list, 7);
list_add_data_tail(&list, 1);
list_add_data_tail(&list, 12);
list_add_data_tail(&list, 1);
list_print(list);
printf("\nLook up 3 in the list\n");
if (list_data_look_up(list, 3)) {
printf("Yes, list has 3\n");
} else {
printf("No, list does not have 3\n");
}
printf("\nLook up 5 in the list\n");
if (list_data_look_up(list, 5)) {
printf("Yes, list has 5\n");
} else {
printf("No, list does not have 5\n");
}
printf("\nRemove 1s from the list\n");
list_remove_node_by_data(&list, 1);
list_print(list);
printf("\nReverse list\n");
list_reverse(&list);
list_print(list);
return 0;
}
Test Output:
Creating link list
1->1->5->6->1->7->1->12->1->NULL
Look up 3 in the list
No, list does not have 3
Look up 5 in the list
Yes, list has 5
Remove 1s from the list
5->6->7->12->NULL
Reverse list
12->7->6->5->NULL
12->7->6->5->NULL
Source Download:
https://github.com/sezginmurat/list_lib.git
Comments