Start your programming journey with one of the most powerful and foundational languages — C. This comprehensive course is designed for absolute beginners as well as intermediate learners who want to build a solid understanding of programming using the C language. Whether you're preparing for college-level programming, cracking technical interviews, or planning to explore systems or embedded development, this course covers everything step-by-step. Through hands-on examples, real-world practice problems, and structured explanations, you’ll learn how to write clean and efficient C code — from your first printf() to advanced data structures and memory management.
In this chapter, we explore two fundamental linear data structures: Stacks and Queues. You will learn how they work and how to implement them using both arrays and linked lists in C.
A Stack follows LIFO (Last In First Out) principle. The last element inserted is the first one to be removed.
push() – Add elementpop() – Remove elementpeek() – View top elementisEmpty() – Check if empty#define MAX 100
int stack[MAX];
int top = -1;
void push(int val) {
if (top == MAX - 1) {
printf("Stack Overflow\n");
return;
}
stack[++top] = val;
}
int pop() {
if (top == -1) {
printf("Stack Underflow\n");
return -1;
}
return stack[top--];
}
struct Node {
int data;
struct Node* next;
};
struct Node* top = NULL;
void push(int val) {
struct Node* newNode = malloc(sizeof(struct Node));
newNode->data = val;
newNode->next = top;
top = newNode;
}
int pop() {
if (top == NULL) return -1;
int val = top->data;
struct Node* temp = top;
top = top->next;
free(temp);
return val;
}
A Queue follows FIFO (First In First Out) principle. The first element inserted is the first to be removed.
enqueue() – Add elementdequeue() – Remove elementisEmpty() – Check if empty#define MAX 100
int queue[MAX];
int front = -1, rear = -1;
void enqueue(int val) {
if (rear == MAX - 1) {
printf("Queue Full\n");
return;
}
if (front == -1) front = 0;
queue[++rear] = val;
}
int dequeue() {
if (front == -1 || front > rear) {
printf("Queue Empty\n");
return -1;
}
return queue[front++];
}
struct Node {
int data;
struct Node* next;
};
struct Node* front = NULL;
struct Node* rear = NULL;
void enqueue(int val) {
struct Node* newNode = malloc(sizeof(struct Node));
newNode->data = val;
newNode->next = NULL;
if (rear == NULL) {
front = rear = newNode;
} else {
rear->next = newNode;
rear = newNode;
}
}
int dequeue() {
if (front == NULL) return -1;
int val = front->data;
struct Node* temp = front;
front = front->next;
if (front == NULL) rear = NULL;
free(temp);
return val;
}
Imagine handling support requests at UdaanPath — a queue is used to process them in the order received (FIFO). For backtracking or undo operations, a stack (LIFO) is more appropriate.
peek() and isEmpty() for both structuresUp next: Trees and Basic Tree Traversals — we’ll explore binary trees and how to traverse them using pre-order, in-order, and post-order logic.