Skip to content

Instantly share code, notes, and snippets.

@lavantien
Created September 30, 2018 08:28
Show Gist options
  • Save lavantien/17b311b63caedc8dfeae1a0df2682801 to your computer and use it in GitHub Desktop.
Save lavantien/17b311b63caedc8dfeae1a0df2682801 to your computer and use it in GitHub Desktop.
Implementation of Linked List and its operations in C
// Warning: Use at least a compiler which has support ISO C99 to compile the program
#include <stdio.h> // For using printf, scanf, puts and putchar
#include <stdlib.h> // For using malloc and free
#include <stdbool.h> // For using bool variable type
struct Node { // DO NOT TYPEDEF THIS!
int data; // Data field
struct Node *next; // Pointer to the next node, if this node is the last node, this pointer point to NULL
};
// "ll" stand for Linked List, "ins" stand for insert, "del" stand for delete, "beg" stand for begin, "pos" stand for position
void llprint(struct Node *); // Print out the list, if the list is empty, it prints EMPTY
struct Node *llclear(struct Node *); // Totally clear the list, after free all memory has been taken, the 'head' point to NULL
size_t llcount(struct Node *); // Return number of members in the list
struct Node *llreverse(struct Node *); // Reverse the list
struct Node *llnewnode(const int); // Simply create and return a new node
struct Node *llinsbeg(struct Node *, const int); // Insert a new node at the beginning of the list
struct Node *llinsend(struct Node *, const int); // Insert a new node at the end of the list
struct Node *llinspos(struct Node *, const int, const size_t pos); // Insert a new node after a given position of the list; if pos <= 0: call llinsend, if pos == 1: call llinsbeg, if pos > llcount: insert a new node at the end of the list
struct Node *lldelbeg(struct Node *); // Delete first node in the list
struct Node *lldelend(struct Node *); // Delete last node in the list
struct Node *lldelpos(struct Node *, const size_t pos); // Delete a node at a given position, which the property of the pos variable is as same as llinspos function
size_t llsearchbeg(struct Node *, const int); // This function return first position which has the data match the given, 0 if not found
size_t llsearchend(struct Node *, const int); // This function return last position which has the data match the given, 0 if not found
size_t llsearch(struct Node *, const int kval, size_t *arrpos); // This function return the number of positions that have the data match kval, and an array that save positions, 0 and NULL pointer for array if not found
struct Node *llsort(struct Node *, const bool mode); // Sort the list in increasing or decreasing order depend on given mode; if mode == true: increasingly sorting, if mode == false: decreasingly sorting
int main(void) {
struct Node *head = NULL; // Create a linked list by setting the head of it
int x;
/* Test inserting and printing */ {
do {
printf("%s", "Enter x: ");
scanf("%d", &x);
if (x < 0) {
continue;
}
//head = llinsbeg(head, x); // Works
head = llinsend(head, x); // Works
llprint(head); // Works
} while (x >= 0);
}
/* Test counting */ {
printf("%llu\n", llcount(head)); // Works
}
/* Test reversing */ {
head = llreverse(head); // Works
llprint(head);
}
/* Test llinspos */ {
head = llinspos(head, 7, 0); // Works
llprint(head);
head = llinspos(head, 8, 1); // Works
llprint(head);
head = llinspos(head, 10, llcount(head)); // Works
llprint(head);
head = llinspos(head, 11, 100); // Works
llprint(head);
head = llinspos(head, 12, 2); // Works
llprint(head);
}
/* Test deleting */ {
head = lldelbeg(head); // Works
llprint(head);
head = lldelend(head); // Works
llprint(head);
head = lldelpos(head, 0); // Works
llprint(head);
head = lldelpos(head, 1); // Works
llprint(head);
head = lldelpos(head, 3); // Works
llprint(head);
head = lldelpos(head, llcount(head)); // Works
llprint(head);
head = lldelpos(head, 100); // Works
llprint(head);
}
/* Test searching */ {
for (int i = 1; i <= 5; i++) {
head = llinsend(head, i);
}
llprint(head);
printf("%llu\n", llsearchbeg(head, 1)); // Works
printf("%llu\n", llsearchbeg(head, 5)); // Works
printf("%llu\n", llsearchbeg(head, 2)); // Works
printf("%llu\n", llsearchbeg(head, 16)); // Works
printf("%llu\n", llsearchend(head, 1)); // Works
printf("%llu\n", llsearchend(head, 5)); // Works
printf("%llu\n", llsearchend(head, 2)); // Works
printf("%llu\n", llsearchend(head, 16)); // Works
size_t arrpos[100];
size_t n = llsearch(head, 2, arrpos); // Works
for (size_t i = 0; i < n; ++i) {
printf("%llu ", arrpos[i]);
}
putchar('\n');
head = llclear(head);
head = llinsend(head, 7);
llprint(head);
printf("%llu\n", llsearchbeg(head, 7)); // Works
printf("%llu\n", llsearchbeg(head, 1)); // Works
printf("%llu\n", llsearchend(head, 7)); // Works
printf("%llu\n", llsearchend(head, 1)); // Works
}
/* Test clearing */ {
head = llclear(head); // Works
llprint(head);
}
puts("PROGRAM_END");
return 0;
}
void llprint(struct Node *head) {
printf("%s", "Current list: ");
if (head == NULL) {
puts("LINKED_LIST_EMPTY");
return;
}
struct Node *temp = head;
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
putchar('\n');
}
struct Node *llclear(struct Node *head) {
if (head == NULL) {
return head;
}
struct Node *temp = head;
while (temp != NULL) {
head = temp->next;
free(temp);
temp = head;
}
return head;
}
size_t llcount(struct Node *head) {
struct Node *temp = head;
int i = 0;
while (temp != NULL) {
++i;
temp = temp->next;
}
return i;
}
struct Node *llreverse(struct Node *head) {
if (head == NULL) {
return head;
}
// run the below code by hand and paper if you don't understand or really wanna see how it works, the same for the rest of code
struct Node *prev = head, *curr = head;
head = curr = prev->next;
prev->next = NULL;
while (curr != NULL) {
head = curr->next;
curr->next = prev;
prev = curr;
curr = head;
}
head = prev;
return head;
}
struct Node *llnewnode(const int x) {
struct Node *newnode = malloc(sizeof *newnode);
newnode->data = x;
newnode->next = NULL;
return newnode;
}
struct Node *llinsbeg(struct Node *head, const int x) {
struct Node *newnode = llnewnode(x);
if (head == NULL) {
head = newnode;
return head;
}
struct Node *temp = head;
head = newnode;
newnode->next = temp;
return head;
}
struct Node *llinsend(struct Node *head, const int x) {
struct Node *newnode = llnewnode(x);
if (head == NULL) {
head = newnode;
return head;
}
struct Node *temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newnode;
return head;
}
struct Node *llinspos(struct Node *head, const int x, const size_t pos) {
struct Node *newnode = NULL;
if (head == NULL) {
newnode = llnewnode(x);
head = newnode;
return head;
}
if (pos == 0) {
head = llinsend(head, x);
return head;
}
if (pos == 1) {
head = llinsbeg(head, x);
return head;
}
newnode = llnewnode(x);
struct Node *temp = head;
size_t i = 1;
while (temp->next != NULL && i < pos) {
temp = temp->next;
++i;
}
newnode->next = temp->next;
temp->next = newnode;
return head;
}
struct Node *lldelbeg(struct Node *head) {
if (head == NULL) {
return head;
}
struct Node *delnode = head;
head = delnode->next;
free(delnode);
return head;
}
struct Node *lldelend(struct Node *head) {
if (head == NULL) {
return head;
}
struct Node *temp = head;
if (temp->next == NULL) {
head = lldelbeg(head);
return head;
}
while (temp->next->next != NULL) {
temp = temp->next;
}
struct Node *delnode = temp->next;
temp->next = NULL;
free(delnode);
return head;
}
struct Node *lldelpos(struct Node *head, const size_t pos) {
if (head == NULL) {
return head;
}
if (pos == 0) {
head = lldelend(head);
return head;
}
if (pos == 1) {
head = lldelbeg(head);
return head;
}
struct Node *temp = head;
if (temp->next == NULL) {
head = lldelbeg(head);
return head;
}
size_t i = 1;
while (temp->next->next != NULL && i < pos - 1) {
temp = temp->next;
++i;
}
struct Node *delnode = temp->next;
temp->next = delnode->next;
free(delnode);
return head;
}
size_t llsearchbeg(struct Node *head, const int kval) {
if (head == NULL) {
return 0;
}
struct Node *temp = head;
size_t i = 1;
while (temp != NULL) {
if (temp->data == kval) {
return i;
}
temp = temp->next;
++i;
}
return 0;
}
size_t llsearchend(struct Node *head, const int kval) {
if (head == NULL) {
return 0;
}
head = llreverse(head);
struct Node *temp = head;
size_t i = 1;
while (temp != NULL) {
if (temp->data == kval) {
break;
}
temp = temp->next;
++i;
}
head = llreverse(head);
return llcount(head) - i + 1;
}
size_t llsearch(struct Node *head, const int kval, size_t *arrpos) {
if (head == NULL) {
return 0;
}
struct Node *temp = head;
size_t i = 1;
size_t res = 0;
while (temp != NULL) {
if (temp->data == kval) {
arrpos[res] = i;
++res;
}
temp = temp->next;
++i;
}
return res;
}
// ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment