As a beginner and curious guy I'm interested in implementing data structures and algorithms from scratch. Here's my implementation of Stack and Queue, the most fundamental data structures.
Are there are any mistakes/ memory leaks in the code that I have missed? How I can improve my implementation.
#include<stdio.h>
#include<stdlib.h>
typedef struct NODE {
int data;
struct NODE *next_node;
} NODE;
NODE *check_queue(NODE *head);
NODE *check_stack(NODE *head);
void push_node(NODE **head, int value);
void enqueue_node(NODE **head, int value, NODE **tail);
int pop(NODE **s_head);
int dequeue(NODE **q_head);
void print_stack(NODE *head);
void print_queue(NODE *head);
void free_memory(NODE **head);
int main(){
NODE *Q_head = NULL;
NODE *Q_tail = NULL;
NODE *S_head = NULL;
/*operations here*/
return 0;
}
/*----- check functions for queue and stack if empty-----------*/
NODE *check_queue(NODE *head){
return head;
}
NODE *check_stack(NODE *head){
return head;
}
/*--------------------------------------------------------------*/
void push_node(NODE **head, int value){
NODE *cache;
cache = (NODE *) malloc(sizeof(NODE));
cache->data = value;
/*first commit / allocate a new head*/
if ((*head) == NULL) {
cache->next_node = NULL;
(*head) = cache; /*assign the cache to head head*/
}
else {
/*point to the previous head*/
cache->next_node = (*head);
(*head) = cache;
}
}
void enqueue_node(NODE **head, int value, NODE **tail) {
NODE *cache;
cache = (NODE *) malloc(sizeof(NODE));
cache->data = value;
cache->next_node = NULL;
if ((*head) == NULL && (*tail) == NULL) {
(*head) = cache; /*assign the cache to head*/
/*now assign tail the job as a cachet head and extends the queue*/
(*tail) = (*head);
}
else {
/*now tail is the representative of head and extened the queue*/
(*tail)->next_node = cache;
(*tail) = cache;
}
}
int pop(NODE **s_head){
if(check_stack((*s_head)) == NULL){
printf("Stack is empty ! ! !\n");
return -1;
}
else {
/*put next head into a cache, free present head, take next head to present head*/
NODE *cache ;
cache = (*s_head)->next_node;
int popped_value = (*s_head)->data;
free((*s_head));
(*s_head) = cache;
return popped_value;
}
}
int dequeue(NODE **q_head){
if(check_queue((*q_head)) == NULL){
printf("queue is empty ! ! !\n");
return -1;
}
else {
/*ditto of stack as we've got queue sequence*/
NODE *cache ;
cache = (*q_head)->next_node;
int dequeued_value = (*q_head)->data;
free((*q_head));
(*q_head) = cache;
return dequeued_value;
}
}
void print_stack(NODE *head){
while (head) {
printf(" %d \n", head->data);
printf(" |\n");
head = head->next_node;
}
/*for further assurance*/
if ( head == NULL){
printf("NULL\n");
}
printf("\n");
}
void print_queue(NODE *q_head){
while (q_head) {
// printf(" %d -> ", head->next_node);
printf(" %d -> ", q_head->data);
q_head = q_head->next_node;
}
/*for further assurance*/
if ( q_head == NULL){
printf("NULL\n");
}
printf("\n");
}
void free_memory(NODE **head){
NODE *cache_head;
while ((*head)) {
/*assign next head to the cache*/
cache_head = (*head)->next_node;
free((*head));
(*head) = cache_head;
}
printf("memory release complete !!! \n");
}