Last active
November 13, 2021 11:03
-
-
Save storca/d9e7c26be3ce1d1e3ba8860f432a78d2 to your computer and use it in GitHub Desktop.
Single Linked list in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file sllist.c | |
* @author storca (storca@mail.com) | |
* @brief Generic implementation of a single-linked list | |
* Cells are added to the left, and deleted on the right | |
* @date 2021-11-11 | |
* | |
* Illustration | |
* | |
* list_add(aa) | |
* list_add(bb) | |
* list_add(cc) | |
* | |
* list --> |C cc| --> |B bb| --> |A aa| | |
*/ | |
#include <stdlib.h> | |
#include <string.h> //memcpy | |
#include <stdio.h> | |
struct Cell; | |
typedef struct { | |
char* content; | |
struct Cell *next; //next is on the right of this cell | |
} Cell; | |
typedef struct { | |
Cell *first; | |
uint lengh; | |
size_t type_size; | |
} List; | |
Cell* cell_init(char* content, Cell *next, size_t type_size) | |
{ | |
Cell *cell; | |
cell = (Cell*) malloc(sizeof(Cell)); //allocate a new cell | |
cell->next = next; | |
cell->content = malloc(type_size); //allocate space for the content of the cell | |
memcpy(cell->content, content, type_size); //copy the content to the newly created cell | |
return cell; | |
} | |
Cell* cell_fetch_recursivly(Cell *cell) | |
{ | |
if(cell->next == NULL) | |
{ | |
return cell; //I am the last one ;( | |
} | |
else | |
{ | |
return cell_fetch_recursivly(cell->next); | |
} | |
} | |
/** | |
* @brief Fetch the cell situated before the last cell | |
* | |
* @param cell Cell from which to start | |
* @return Cell* The cell before the last cell | |
*/ | |
Cell* cell_fetch(Cell *cell) | |
{ | |
Cell *curr = cell; | |
Cell *prev = NULL; | |
while(curr->next != NULL) | |
{ | |
prev = curr; | |
curr = curr->next; | |
} | |
return prev; | |
} | |
void cell_free(Cell *cell) | |
{ | |
free(cell->content); //free the contents of the cell | |
//free(cell->next); | |
free(cell); //free the space reserved by the cell | |
} | |
List* list_init(size_t type_size) | |
{ | |
List *list = malloc(sizeof(List)); | |
list->lengh = 0; | |
list->first = NULL; | |
list->type_size = type_size; | |
return list; //return a pointer to the newly allocated list | |
} | |
int list_is_empty(List *list) | |
{ | |
return list->lengh < 1; | |
} | |
void list_add(List *list, char* content) | |
{ | |
list->first = cell_init(content, list->first, list->type_size); | |
list->lengh += 1; | |
} | |
/** | |
* @brief Returns a pointer to the last element of the list | |
* And removes the cell in which the item was contained | |
* | |
* @param list | |
* @return char* | |
*/ | |
char* list_remove(List *list) | |
{ | |
if(!list_is_empty(list)) | |
{ | |
Cell *before_last = cell_fetch(list->first); | |
Cell *curr; | |
if(before_last == NULL) | |
{ | |
curr = list->first; | |
} | |
else | |
{ | |
curr = before_last->next; | |
before_last->next = NULL; | |
} | |
char* content = curr->content; | |
cell_free(curr); | |
list->lengh -= 1; | |
return content; | |
} | |
} | |
void list_print(List *list) | |
{ | |
Cell *curr = list->first; | |
printf("list --> "); | |
while (curr->next != NULL) | |
{ | |
printf("|cell %p| --> ", (void*)curr); | |
curr = curr->next; | |
} | |
printf("NULL (end)\n"); | |
} | |
/** | |
* @brief Return the last element of the list | |
* | |
* @param list | |
* @return char* | |
*/ | |
char* list_last(List *list) | |
{ | |
char* content; | |
Cell *last = cell_fetch_recursivly(list->first); | |
content = last->content; | |
return content; | |
} | |
/** | |
* @brief Delete a list and deallocate all of it's contents | |
* Complexity is O(n) | |
* | |
* @param list | |
*/ | |
void list_delete(List *list) | |
{ | |
if(list->lengh > 0) | |
{ | |
//Free each cell on the list | |
Cell *curr = list->first; | |
Cell *next = NULL; | |
while (curr->next != NULL) | |
{ | |
next = curr->next; | |
cell_free(curr); | |
curr = next; | |
} | |
cell_free(curr); //do not forget the last cell | |
} | |
free(list); | |
} | |
int main() | |
{ | |
int data[20]; | |
List *list = list_init(sizeof(int)); | |
for (size_t i = 0; i < 20; i++) | |
{ | |
data[i] = i*23; | |
list_add(list, (char*)&data[i]); | |
} | |
list_print(list); | |
printf("list_remove : %i\n", *(int*)list_remove(list)); | |
printf("list_last : %i\n", *(int*)list_last(list)); | |
list_delete(list); | |
printf("List size : %i\n", sizeof(List)); | |
printf("Cell size : %i\n", sizeof(Cell)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment