Created
September 30, 2018 08:28
-
-
Save lavantien/17b311b63caedc8dfeae1a0df2682801 to your computer and use it in GitHub Desktop.
Implementation of Linked List and its operations 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
// 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