I have implemented my singly linked list in C and I tried to do it with the most efficient code as possible. Is there any place for improvement?
This post is the second version.
First version of this question
Third version of this question
These are the operations I defined:
- append (insert at the end -- 2 versions, with one more efficient O(1))
- prepend (insert at the beginning)
- insert (insert between the head and tail)
- delete (delete nodes)
- swap (swap nodes values)
- clear (delete all nodes)
- print (print elements)
- reverse (reverse elements)
- search (get the index of element if it exists)
- size (get size of the list)
- isEmpty (check if the list is empty)
- rotate (rotate clockwise by k)
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node;
Node* head = NULL;
Node* prev = NULL;
Node* create_node(int elm) {
Node* node = malloc(sizeof * node);
if (!node) exit(EXIT_FAILURE);
node->data = elm;
node->next = NULL;
return node;
}
Node* node_k(int i) {
int k = 0;
Node* node = head;
while (k != i) {
k += 1;
node = node->next;
}
return node;
}
void append_sll_1(int elm) { //O(1)
Node* cur = create_node(elm);
if (!head) {
head = cur;
prev = head;
}
else {
prev->next = cur;
prev = cur;
}
}
void append_sll_2(int elm) { //O(n)
Node* temp = create_node(elm);
if (!head) {
head = temp;
}
else {
Node* last = head;
while (last->next != NULL) {
last = last->next;
}
last->next = temp;
}
}
void prepend(int elm) {
Node* updated_head = create_node(elm);
if (!head) {
head = updated_head;
}
else {
updated_head->next = head;
head = updated_head;
}
}
void insert_sll(int elm, int i) {
int k = 1; // we don't prepend, so K > 0
Node* cur = create_node(elm);
if (!head) {
head = cur;
}
else {
Node* last = head;
while (k != i - 1) { // 1 < i < n | 1:prepend, n:append
k += 1;
last = last->next;
}
cur->next = last->next;
last->next = cur;
}
}
void delete_sll(int elm) {
Node* node = head;
if (head->data == elm) {
head = head->next;
free(node);
}
else {
while (node->data != elm) {
prev = node;
node = node->next;
}
prev->next = node->next;
free(node);
}
}
int is_empty_sll() { //O(1)
return head == NULL;
}
int size_sll() { //O(n)
int count = 0;
Node* last = head;
while (last) {
count += 1;
last = last->next;
}
return count;
}
int search_sll(int elm) { //O(n)
int i = 0;
Node* last = head;
while (last->data != elm) {
i += 1;
last = last->next;
}
return i;
}
void swap_sll(int i, int j) {//O(n) --swap value of position i with j
Node* node_i = node_k(i);
Node* node_j = node_k(j);
int temp = node_i->data;
node_i->data = node_j->data;
node_j->data = temp;
}
void print_sll() {
Node* trav = head;
while (trav) {
printf("%d ", trav->data);
trav = trav->next;
}
printf("\n");
}
void reverse_sll() {
prev = head;
Node* cur = head->next;
Node* next_node = cur;
while (next_node) {
next_node = cur->next;
cur->next = prev;
prev = cur;
cur = next_node;
}
head->next = next_node;
head = prev;
}
void clear_sll() { //O(n)
while (head) {
Node* temp = head;
head = head->next;
free(temp);
}
printf("List Cleared!\n");
}
void rotate_sll(int k) {
int size = size_sll();
Node* tail = head;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = head;
Node* k_node = node_k(k);
for (int i = 0; i < size; i++) {
printf("%d ", k_node->data);
k_node = k_node->next;
}
}
// void sort_sll() {//
// }
int main() {
append_sll_1(1);
append_sll_1(2);
append_sll_1(4);
insert_sll(3, 3);
prepend(0);
print_sll();
printf("size: %d\n", size_sll());
printf("index of 3 is: %d\n", search_sll(3));
delete_sll(2);
print_sll();
swap_sll(0, 1);
print_sll();
reverse_sll();
print_sll();
clear_sll();
print_sll();
return 0;
}
Do you have any improvement ideas? I tried to make it as simple and code friendly as possible for future learners, it would help if you find it a stable implementation to upvote it. There are many implementations online, and many of them are just very confusing to follow, whereas this one, you can just take a paper and pen, and everything becomes clear in front of your eyes.
node_k()
not have protection from iterating past the end of the list? \$\endgroup\$