Arrays, Strings, Linked Lists, Stacks, Queues & Pointers in C: DSA Fundamentals with Code Examples

1. What is an array in C?

An array is a fixed-size, ordered collection of elements of the same data type, stored in contiguous memory locations, accessed by an index starting at 0.

2. How do you declare an array in C?

Declare an array by specifying the data type, name, and size. Example:

int arr[5]; // Declares an array of 5 integers
int arr[5] = {1, 2, 3, 4, 5}; // Initialized array
      

3. How do you traverse an array in C?

Traversal involves accessing each element using a loop. Example:

#include 

void traverse(int arr[], int n) {
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    traverse(arr, 5); // Output: 1 2 3 4 5
    return 0;
}
      

4. How do you insert an element into an array?

Shift elements to the right to make space at the desired index, then insert the new element. Example:

#include 

void insert(int arr[], int *n, int pos, int value) {
    if (*n >= pos && pos >= 0) {
        for (int i = *n; i > pos; i--) { // Shift elements
            arr[i] = arr[i - 1];
        }
        arr[pos] = value; // Insert value
        (*n)++; // Increase size
    }
}

int main() {
    int arr[10] = {1, 2, 3, 4, 5};
    int n = 5;
    insert(arr, &n, 2, 99); // Insert 99 at index 2
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]); // Output: 1 2 99 3 4 5
    }
    return 0;
}
      

5. How do you delete an element from an array?

Shift elements to the left to fill the gap at the desired index. Example:

#include 

void delete(int arr[], int *n, int pos) {
    if (pos >= 0 && pos < *n) {
        for (int i = pos; i < *n - 1; i++) { // Shift elements
            arr[i] = arr[i + 1];
        }
        (*n)--; // Decrease size
    }
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int n = 5;
    delete(arr, &n, 2); // Delete element at index 2
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]); // Output: 1 2 4 5
    }
    return 0;
}
      

6. What are the advantages and disadvantages of arrays?

7. What is the time complexity of array operations?

8. What is a string in C?

A string in C is an array of characters terminated by a null character (\0). Example: char str[] = "Hello";.

9. How do you declare and initialize a string in C?

Declare as a char array or pointer, initialized with a string literal or character-by-character. Example:

char str1[] = "Hello"; // Array
char *str2 = "World"; // Pointer (read-only)
char str3[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
      

10. What are common string operations in C?

Common operations (using <string.h>):

11. Can you give an example of string manipulation in C?

Example: Reverse a string.

#include 
#include 

void reverseString(char str[]) {
    int n = strlen(str);
    for (int i = 0, j = n - 1; i < j; i++, j--) {
        char temp = str[i];
        str[i] = str[j];
        str[j] = temp;
    }
}

int main() {
    char str[] = "Hello";
    reverseString(str);
    printf("%s\n", str); // Output: olleH
    return 0;
}
      

12. What are the challenges with strings in C?

13. What is the time complexity of string operations?

14. What is a linked list?

A linked list is a dynamic data structure where nodes (containing data and a pointer to the next node) are linked sequentially. Unlike arrays, nodes are not stored contiguously.

15. What is a singly linked list?

A singly linked list has nodes with a data element and a pointer to the next node. Example:

#include 
#include 

struct Node {
    int data;
    struct Node* next;
};

void printList(struct Node* head) {
    while (head != NULL) {
        printf("%d ", head->data);
        head = head->next;
    }
    printf("\n");
}

int main() {
    struct Node* head = malloc(sizeof(struct Node));
    head->data = 1;
    head->next = malloc(sizeof(struct Node));
    head->next->data = 2;
    head->next->next = NULL;
    printList(head); // Output: 1 2
    free(head->next);
    free(head);
    return 0;
}
      

16. What is a doubly linked list?

A doubly linked list has nodes with pointers to both the next and previous nodes, allowing bidirectional traversal. Example structure:

struct Node {
    int data;
    struct Node* next;
    struct Node* prev;
};
      

17. What is a circular linked list?

A circular linked list is a singly or doubly linked list where the last node points back to the first node, forming a loop. Example (singly circular):

#include 
#include 

struct Node {
    int data;
    struct Node* next;
};

void printCircularList(struct Node* head) {
    if (head == NULL) return;
    struct Node* temp = head;
    do {
        printf("%d ", temp->data);
        temp = temp->next;
    } while (temp != head);
    printf("\n");
}

int main() {
    struct Node* head = malloc(sizeof(struct Node));
    head->data = 1;
    head->next = malloc(sizeof(struct Node));
    head->next->data = 2;
    head->next->next = head; // Circular link
    printCircularList(head); // Output: 1 2
    free(head->next);
    free(head);
    return 0;
}
      

18. What are the operations on linked lists?

19. What are the advantages and disadvantages of linked lists?

20. What is the time complexity of linked list operations?

21. What is a stack?

A stack is a linear data structure following the Last-In-First-Out (LIFO) principle, where elements are added (pushed) and removed (popped) from the top.

22. How do you implement a stack in C?

Implement using an array or linked list. Example (array-based):

#include 
#define MAX 100

struct Stack {
    int arr[MAX];
    int top;
};

void init(struct Stack* s) {
    s->top = -1;
}

void push(struct Stack* s, int value) {
    if (s->top < MAX - 1) {
        s->arr[++(s->top)] = value;
    }
}

int pop(struct Stack* s) {
    if (s->top >= 0) {
        return s->arr[(s->top)--];
    }
    return -1; // Stack empty
}

int main() {
    struct Stack s;
    init(&s);
    push(&s, 1);
    push(&s, 2);
    printf("%d\n", pop(&s)); // Output: 2
    printf("%d\n", pop(&s)); // Output: 1
    return 0;
}
      

23. What are the applications of stacks?

24. What is the time complexity of stack operations?

25. What are the advantages and disadvantages of stacks?

26. What is a queue?

A queue is a linear data structure following the First-In-First-Out (FIFO) principle, where elements are added (enqueued) at the rear and removed (dequeued) from the front.

27. How do you implement a simple queue in C?

Example (array-based simple queue):

#include 
#define MAX 100

struct Queue {
    int arr[MAX];
    int front, rear;
};

void init(struct Queue* q) {
    q->front = q->rear = -1;
}

void enqueue(struct Queue* q, int value) {
    if (q->rear < MAX - 1) {
        if (q->front == -1) q->front = 0;
        q->arr[++(q->rear)] = value;
    }
}

int dequeue(struct Queue* q) {
    if (q->front <= q->rear && q->front != -1) {
        return q->arr[(q->front)++];
    }
    return -1; // Queue empty
}

int main() {
    struct Queue q;
    init(&q);
    enqueue(&q, 1);
    enqueue(&q, 2);
    printf("%d\n", dequeue(&q)); // Output: 1
    printf("%d\n", dequeue(&q)); // Output: 2
    return 0;
}
      

28. What is a circular queue?

A circular queue connects the rear to the front, reusing empty spaces in an array to avoid overflow. Example:

#include 
#define MAX 5

struct CircularQueue {
    int arr[MAX];
    int front, rear;
};

void init(struct CircularQueue* q) {
    q->front = q->rear = -1;
}

void enqueue(struct CircularQueue* q, int value) {
    if ((q->rear + 1) % MAX == q->front) return; // Full
    if (q->front == -1) q->front = 0;
    q->rear = (q->rear + 1) % MAX;
    q->arr[q->rear] = value;
}

int dequeue(struct CircularQueue* q) {
    if (q->front == -1) return -1; // Empty
    int value = q->arr[q->front];
    if (q->front == q->rear) q->front = q->rear = -1;
    else q->front = (q->front + 1) % MAX;
    return value;
}

int main() {
    struct CircularQueue q;
    init(&q);
    enqueue(&q, 1);
    enqueue(&q, 2);
    printf("%d\n", dequeue(&q)); // Output: 1
    return 0;
}
      

29. What is a priority queue?

A priority queue assigns priorities to elements, dequeuing the highest-priority element first. It can be implemented using arrays, linked lists, or heaps (heap is most efficient).

30. What are the applications of queues?

31. What is the time complexity of queue operations?

Simple/Circular Queue (array-based):

Priority Queue (heap-based):

32. What is a pointer in C?

A pointer is a variable that stores the memory address of another variable. It allows direct memory manipulation and is essential for dynamic data structures like linked lists.

33. How do you declare and use a pointer in C?

Declare with *, assign an address with &, and dereference with *. Example:

#include 

int main() {
    int x = 10;
    int* ptr = &x; // Pointer to x
    printf("%d\n", *ptr); // Output: 10 (dereference)
    *ptr = 20; // Change x via pointer
    printf("%d\n", x); // Output: 20
    return 0;
}
      

34. What is dynamic memory allocation in C?

Dynamic memory allocation uses malloc, calloc, realloc, and free to manage memory at runtime. Example:

#include 
#include 

int main() {
    int* arr = (int*)malloc(5 * sizeof(int)); // Allocate for 5 integers
    for (int i = 0; i < 5; i++) {
        arr[i] = i + 1;
    }
    printf("%d\n", arr[0]); // Output: 1
    free(arr); // Deallocate memory
    return 0;
}
      

35. What are common pointer-related errors?

36. How do pointers relate to data structures?

Pointers enable dynamic structures like linked lists, stacks, and queues by linking nodes or managing memory allocation for arrays and trees.

37. What is the difference between malloc and calloc?

38. How do you avoid memory leaks in C?

Always call free() for dynamically allocated memory, avoid losing pointers to allocated memory, and use tools like Valgrind to detect leaks.

39. What is the difference between stack and heap memory?