Skip to content

Data structure in C

Recursion:

Recursion is a programming technique where a function calls itself directly or indirectly. It's often used in solving problems that can be broken down into smaller, similar sub-problems.

Example: Factorial calculation using recursion.

#include <stdio.h>

int factorial(int n) {
    if (n <= 1)
        return 1;
    else
        return n * factorial(n - 1);
}

int main() {
    int num = 5;
    printf("Factorial of %d = %d\n", num, factorial(num));
    return 0;
}

Arrays:

Arrays are collections of elements of the same data type stored in contiguous memory locations.

Example: Finding the maximum element in an array.

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int size = sizeof(arr) / sizeof(arr[0]);
    int max = arr[0];

    for (int i = 1; i < size; i++) {
        if (arr[i] > max)
            max = arr[i];
    }

    printf("Maximum element in the array: %d\n", max);

    return 0;
}

Stack:

A stack is a data structure that follows the Last In, First Out (LIFO) principle. Elements are inserted and removed from the same end, called the top.

Example: Implementation of a stack using an array.

#include <stdio.h>

#define MAX_SIZE 100

int stack[MAX_SIZE];
int top = -1;

void push(int item) {
    if (top == MAX_SIZE - 1) {
        printf("Stack Overflow\n");
        return;
    }
    stack[++top] = item;
}

int pop() {
    if (top == -1) {
        printf("Stack Underflow\n");
        return -1;
    }
    return stack[top--];
}

int main() {
    push(10);
    push(20);
    push(30);

    printf("Popped item: %d\n", pop());
    printf("Popped item: %d\n", pop());

    return 0;
}

Queues:

A queue is a data structure that follows the First In, First Out (FIFO) principle. Elements are inserted from the rear and removed from the front.

Example: Implementation of a queue using an array.

#include <stdio.h>

#define MAX_SIZE 100

int queue[MAX_SIZE];
int front = -1, rear = -1;

void enqueue(int item) {
    if (rear == MAX_SIZE - 1) {
        printf("Queue Overflow\n");
        return;
    }
    if (front == -1)
        front = 0;
    queue[++rear] = item;
}

int dequeue() {
    if (front == -1 || front > rear) {
        printf("Queue Underflow\n");
        return -1;
    }
    return queue[front++];
}

int main() {
    enqueue(10);
    enqueue(20);
    enqueue(30);

    printf("Dequeued item: %d\n", dequeue());
    printf("Dequeued item: %d\n", dequeue());

    return 0;
}

Linked List:

A linked list is a linear data structure where elements are stored in nodes, and each node points to the next node in the sequence.

Example: Implementation of a singly linked list.

#include <stdio.h>
#include <stdlib.h>

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

struct Node *head = NULL;

void insert(int value) {
    struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
    newNode->data = value;
    newNode->next = NULL;
    if (head == NULL) {
        head = newNode;
        return;
    }
    struct Node *temp = head;
    while (temp->next != NULL)
        temp = temp->next;
    temp->next = newNode;
}

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

int main() {
    insert(10);
    insert(20);
    insert(30);
    display();
    return 0;
}

Trees:

A tree is a hierarchical data structure consisting of nodes connected by edges. It has a root node and zero or more child nodes.

Example: Implementation of a binary tree.

#include <stdio.h>
#include <stdlib.h>

struct TreeNode {
    int data;
    struct TreeNode *left;
    struct TreeNode *right;
};

struct TreeNode *createNode(int value) {
    struct TreeNode *newNode = (struct TreeNode *)malloc(sizeof(struct TreeNode));
    newNode->data = value;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

int main() {
    struct TreeNode *root = createNode(1);
    root->left = createNode(2);
    root->right = createNode(3);
    root->left->left = createNode(4);
    root->left->right = createNode(5);
    return 0;
}

Binary Search Trees:

A binary search tree (BST) is a binary tree in which the left child of a node has a value less than the node, and the right child has a value greater than the node.

Example: Insertion in a binary search tree.

#include <stdio.h>
#include <stdlib.h>

struct TreeNode {
    int data;
    struct TreeNode *left;
    struct TreeNode *right;
};

struct TreeNode *createNode(int value) {
    struct TreeNode *newNode = (struct TreeNode *)malloc(sizeof(struct TreeNode));
    newNode->data = value;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

struct TreeNode *insert(struct TreeNode *root, int value) {
    if (root == NULL)
        return createNode(value);
    if (value < root->data)
        root->left = insert(root->left, value);
    else if (value > root->data)
        root->right = insert(root->right, value);
    return root;
}

void inorderTraversal(struct TreeNode *root) {
    if (root != NULL) {
        inorderTraversal(root->left);
        printf("%d ", root->data);
        inorderTraversal(root->right);
    }
}

int main() {
    struct TreeNode *root = NULL;
    root = insert(root, 50);
    insert(root, 30);
    insert(root, 20);
    insert(root, 40);
    insert(root, 70);
    insert(root, 60);
    insert(root, 80);
    inorderTraversal(root);
    return 0;
}

Binary Heaps:

A binary heap is a complete binary tree that satisfies the heap property. It can be a min-heap or max-heap.

Example: Insertion in a min-heap.

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

struct MinHeap {
    int *array;
    int size;
    int capacity;
};

struct MinHeap *createMinHeap(int capacity) {
    struct MinHeap *heap = (struct MinHeap *)malloc(sizeof(struct MinHeap));
    heap->capacity = capacity;
    heap->size = 0;
    heap->array = (int *)malloc(capacity * sizeof(int));
    return heap;
}

void insert(struct MinHeap *heap, int value) {
    if (heap->size == heap->capacity) {
        printf("Heap Overflow\n");
        return;
    }
    int i = heap->size;
    heap->array[i] = value;
    heap->size++;

    while (i > 0 && heap->array[i] < heap->array[(i - 1) / 2]) {
        // Swap parent and child
        int temp = heap->array[i];
        heap->array[i] = heap->array[(i - 1) / 2];
        heap->array[(i - 1) / 2] = temp;
        i = (i - 1) / 2;
    }
}

void display(struct MinHeap *heap) {
    for (int i = 0; i < heap->size; i++)
        printf("%d ", heap->array[i]);
    printf("\n");
}

int main() {
    struct MinHeap *heap = createMinHeap(MAX_SIZE);
    insert(heap, 3);
    insert(heap, 2);
    insert(heap, 1);
    insert(heap, 15);
    insert(heap, 5);
    insert(heap, 4);
    insert(heap, 45);
    display(heap);
    return 0;
}

Graphs:

A graph is a collection of nodes (vertices) and edges that connect pairs of nodes. It can be directed or undirected.

Example: Implementation of an undirected graph using adjacency list.

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int vertex;
    struct ListNode *next;
};

struct Graph {
    int numVertices;
    struct ListNode **adjLists;
};

struct ListNode *createNode(int vertex) {
    struct ListNode *newNode = (struct ListNode *)malloc(sizeof(struct ListNode));
    newNode->vertex = vertex;
    newNode->next = NULL;
    return newNode;
}

struct Graph *createGraph(int numVertices) {
    struct Graph *graph = (struct Graph *)malloc(sizeof(struct Graph));
    graph->numVertices = numVertices;
    graph->adjLists = (struct ListNode **)malloc(numVertices * sizeof(struct ListNode *));
    for (int i = 0; i < numVertices; i++)
        graph->adjLists[i] = NULL;
    return graph;
}

void addEdge(struct Graph *graph, int src, int dest) {
    struct ListNode *newNode = createNode(dest);
    newNode->next = graph->adjLists[src];
    graph->adjLists[src] = newNode;

    newNode = createNode(src);
    newNode->next = graph->adjLists[dest];
    graph->adjLists[dest] = newNode;
}

void display(struct Graph *graph) {
    for (int i = 0; i < graph->numVertices; i++) {
        struct ListNode *temp = graph->adjLists[i];
        printf("Adjacency list of vertex %d: ", i);
        while (temp != NULL) {
            printf("%d -> ", temp->vertex);
            temp = temp->next;
        }
        printf("NULL\n");
    }
}

int main() {
    struct Graph *graph = createGraph(4);
    addEdge(graph, 0, 1);
    addEdge(graph, 0, 2);
    addEdge(graph, 1, 2);
    addEdge(graph, 2, 3);
    display(graph);
    return 0;
}