C Programs: Exercises 1-15
1. Arithmetic operations on pointers
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int *p = arr; // points to arr[0]
printf("Array base address: %p\\n", (void*)arr);
printf("Pointer p points to: %p, value = %d\\n",
(void*)p, *p);
// Pointer arithmetic
p++; // next integer
printf("After p++ -> address: %p, value
= %d\\n", (void*)p, *p);
p += 2; // move two integers ahead
printf("After p += 2 -> address: %p,
value = %d\\n", (void*)p, *p);
// Difference between pointers
int *start = arr;
int diff = p -
start; // number of elements between
printf("Number of elements between p and start: %d\\n", diff);
// Access via index using pointer
printf("arr[4] via pointer: %d\\n", *(arr + 4));
return 0;
}
2. Dynamic memory management functions (malloc, calloc, realloc, free)
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5;
int *a = (int*)malloc(n *
sizeof(int));
if (!a) { perror("malloc"); return 1; }
for (int i = 0; i < n; ++i) a[i] = (i+1) * 10;
printf("Allocated array using malloc:\\n");
for (int i = 0; i < n; ++i) printf("%d ", a[i]);
printf("\\n");
// Reallocate to larger size
n = 8;
int *b = (int*)realloc(a, n * sizeof(int));
if (!b) { perror("realloc"); free(a); return 1; }
// Initialize new elements
for (int i = 5; i < n;
++i) b[i] = (i+1) * 10;
printf("After realloc to size 8:\\n");
for (int i = 0; i < n; ++i) printf("%d
", b[i]);
printf("\\n");
// Using calloc
int m = 4;
int *c = (int*)calloc(m, sizeof(int)); //
zero-initialized
if (!c) { perror("calloc"); free(b); return 1; }
printf("Calloc array (zeros): ");
for (int i = 0; i < m; ++i) printf("%d ", c[i]);
printf("\\n");
free(b);
free(c);
return 0;
}
3. Selection sort
#include <stdio.h>
void selectionSort(int arr[], int n) {
for (int i = 0; i < n-1; ++i) {
int
min_idx = i;
for (int j = i+1; j < n; ++j)
if (arr[j] < arr[min_idx]) min_idx = j;
// swap
int tmp = arr[i]; arr[i] = arr[min_idx]; arr[min_idx] = tmp;
}
}
int main() {
int a[]
= {64, 25, 12, 22, 11};
int n = sizeof(a)/sizeof(a[0]);
selectionSort(a, n);
printf("Sorted array:
");
for (int i = 0; i < n; ++i) printf("%d ", a[i]);
printf("\\n");
return 0;
}
4. Insertion sort
#include <stdio.h>
void insertionSort(int arr[], int n) {
for (int i = 1; i < n; ++i) {
int key =
arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
}
int main() {
int a[] = {12, 11, 13, 5, 6};
int n =
sizeof(a)/sizeof(a[0]);
insertionSort(a, n);
printf("Sorted array: ");
for (int i = 0; i < n; ++i)
printf("%d ", a[i]);
printf("\\n");
return 0;
}
5. Bubble sort
#include <stdio.h>
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n-1; ++i) {
int
swapped = 0;
for (int j = 0; j < n-i-1; ++j) {
if (arr[j] > arr[j+1]) {
int tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp;
swapped = 1;
}
}
if (!swapped) break;
}
}
int main() {
int a[] = {5, 1, 4, 2, 8};
int n = sizeof(a)/sizeof(a[0]);
bubbleSort(a, n);
printf("Sorted array: ");
for (int i = 0; i < n; ++i) printf("%d ", a[i]);
printf("\\n");
return 0;
}
6. Quick sort (recursive)
#include <stdio.h>
void swap(int *a, int *b) {
int t = *a; *a = *b; *b = t;
}
int partition(int arr[],
int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j <= high-1; ++j) {
if (arr[j] < pivot) {
++i;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i+1],
&arr[high]);
return i+1;
}
void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi-1);
quickSort(arr, pi+1, high);
}
}
int main() {
int a[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(a)/sizeof(a[0]);
quickSort(a, 0,
n-1);
printf("Sorted array: ");
for (int i = 0; i < n; ++i) printf("%d ", a[i]);
printf("\\n");
return 0;
}
7. Linear search
#include <stdio.h>
int linearSearch(int arr[], int n, int key) {
for (int i = 0; i < n; ++i)
if
(arr[i] == key) return i;
return -1;
}
int main() {
int a[] = {2, 3, 4, 10, 40};
int n =
sizeof(a)/sizeof(a[0]);
int key = 10;
int res = linearSearch(a, n, key);
if (res != -1)
printf("Element found at index %d\\n", res);
else printf("Element not found\\n");
return 0;
}
8. Binary search (iterative)
#include <stdio.h>
int binarySearch(int arr[], int n, int key) {
int low = 0, high = n-1;
while (low
<= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == key) return mid;
else if
(arr[mid] < key) low = mid + 1;
else high = mid - 1;
}
return -1;
}
int main() {
int a[]
= {2, 3, 4, 10, 40};
int n = sizeof(a)/sizeof(a[0]);
int key = 10;
int res = binarySearch(a, n,
key);
if (res != -1) printf("Element found at index %d\\n", res);
else printf("Element not found\\n");
return 0;
}
9. Stack using arrays
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
typedef struct {
int arr[MAX];
int top;
}
Stack;
void init(Stack *s) { s->top = -1; }
int isEmpty(Stack *s) { return s->top == -1; }
int isFull(Stack
*s) { return s->top == MAX-1; }
void push(Stack *s, int x) {
if (isFull(s)) { printf("Stack
overflow\\n"); return; }
s->arr[++s->top] = x;
}
int pop(Stack *s) {
if (isEmpty(s)) { printf("Stack
underflow\\n"); return -1; }
return s->arr[s->top--];
}
int peek(Stack *s) {
if (isEmpty(s)) {
printf("Stack is empty\\n"); return -1; }
return s->arr[s->top];
}
int main() {
Stack s; init(&s);
push(&s, 10); push(&s, 20); push(&s, 30);
printf("Top element: %d\\n", peek(&s));
printf("Popped:
%d\\n", pop(&s));
printf("Top after pop: %d\\n", peek(&s));
return 0;
}
10. Queue using arrays (linear queue)
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
typedef struct {
int arr[MAX];
int front,
rear;
} Queue;
void init(Queue *q) { q->front = 0; q->rear = -1; }
int isEmpty(Queue *q) { return q->front >
q->rear; }
int isFull(Queue *q) { return q->rear == MAX-1; }
void enqueue(Queue *q, int x) {
if
(isFull(q)) { printf("Queue overflow\\n"); return; }
q->arr[++q->rear] = x;
}
int dequeue(Queue *q) {
if (isEmpty(q)) { printf("Queue underflow\\n"); return -1; }
return q->arr[q->front++];
}
int main() {
Queue q; init(&q);
enqueue(&q, 10); enqueue(&q, 20); enqueue(&q, 30);
printf("Dequeued: %d\\n",
dequeue(&q));
printf("Dequeued: %d\\n", dequeue(&q));
return 0;
}
11. Circular queue using arrays
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
typedef struct {
int arr[MAX];
int front, rear;
int size;
} CircQueue;
void init(CircQueue *q) { q->front = 0; q->rear = -1; q->size = 0; }
int
isEmpty(CircQueue *q) { return q->size == 0; }
int isFull(CircQueue *q) { return q->size == MAX; }
void
enqueue(CircQueue *q, int x) {
if (isFull(q)) { printf("Circular Queue overflow\\n"); return; }
q->rear = (q->rear + 1) % MAX;
q->arr[q->rear] = x;
q->size++;
}
int dequeue(CircQueue *q) {
if
(isEmpty(q)) { printf("Circular Queue underflow\\n"); return -1; }
int val = q->arr[q->front];
q->front = (q->front + 1) % MAX;
q->size--;
return val;
}
int main() {
CircQueue q; init(&q);
enqueue(&q, 1); enqueue(&q, 2); enqueue(&q, 3); enqueue(&q, 4); enqueue(&q, 5);
printf("Dequeued: %d\\n",
dequeue(&q));
enqueue(&q, 6);
while (!isEmpty(&q)) printf("%d ", dequeue(&q));
printf("\\n");
return 0;
}
12. Evaluate postfix expression
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#define MAX
100
typedef struct {
double st[MAX];
int top;
} Stack;
void init(Stack *s) { s->top = -1; }
void
push(Stack *s, double v) { s->st[++s->top] = v; }
double pop(Stack *s) { return s->st[s->top--]; }
double
evalPostfix(const char *expr) {
Stack s; init(&s);
int len = strlen(expr);
for (int i = 0; i <
len; ++i) {
if (expr[i] == ' ' || expr[i] == '\\t') continue;
if (isdigit(expr[i]) || (expr[i]
== '-' && isdigit(expr[i+1]))) {
char buf[64]; int k = 0;
// support multi-digit and
negative numbers
if (expr[i] == '-') buf[k++] = expr[i++];
while (i < len &&
(isdigit(expr[i]) || expr[i]=='.')) buf[k++] = expr[i++];
buf[k] = '\\0'; --i;
push(&s, atof(buf));
} else {
double b = pop(&s), a = pop(&s), r = 0;
switch
(expr[i]) {
case '+': r = a + b; break;
case '-': r = a - b; break;
case '*': r = a * b; break;
case '/': r = a / b; break;
case '^': r = pow(a,
b); break;
default: printf("Unknown operator %c\\n", expr[i]); return 0;
}
push(&s, r);
}
}
return pop(&s);
}
int main() {
const char *expr = "5 1 2 + 4 * + 3 -";
// example -> 14
printf("Postfix: %s\\n", expr);
double res = evalPostfix(expr);
printf("Result =
%g\\n", res);
return 0;
}
13. Singly linked list (insert, delete, display)
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
Node* insertAtBeginning(Node *head, int val) {
Node *n = (Node*)malloc(sizeof(Node));
n->data = val;
n->next = head;
return n;
}
Node* deleteValue(Node *head, int val) {
Node *cur = head, *prev = NULL;
while (cur) {
if (cur->data == val) {
if (prev) prev->next = cur->next;
else
head = cur->next;
free(cur);
return head;
}
prev = cur; cur =
cur->next;
}
return head;
}
void display(Node *head) {
Node *cur = head;
while (cur) {
printf("%d -> ", cur->data); cur = cur->next; }
printf("NULL\\n");
}
int main() {
Node *head = NULL;
head = insertAtBeginning(head, 30);
head = insertAtBeginning(head, 20);
head = insertAtBeginning(head,
10);
printf("List: "); display(head);
head = deleteValue(head, 20);
printf("After deleting 20: ");
display(head);
// free remaining nodes
while (head) { Node *t = head; head = head->next; free(t); }
return 0;
}
14. Doubly linked list (insert, delete, display)
#include <stdio.h>
#include <stdlib.h>
typedef struct DNode {
int data;
struct DNode *prev, *next;
}
DNode;
DNode* insertAtFront(DNode *head, int val) {
DNode *n = (DNode*)malloc(sizeof(DNode));
n->data
= val; n->prev = NULL; n->next = head;
if (head) head->prev = n;
return n;
}
DNode* deleteValue(DNode
*head, int val) {
DNode *cur = head;
while (cur) {
if (cur->data == val) {
if
(cur->prev) cur->prev->next = cur->next;
else head = cur->next;
if (cur->next)
cur->next->prev = cur->prev;
free(cur);
return head;
}
cur =
cur->next;
}
return head;
}
void displayForward(DNode *head) {
DNode *cur = head;
while (cur)
{ printf("%d <-> ", cur->data); cur = cur->next; }
printf("NULL\\n");
}
int main() {
DNode *head =
NULL;
head = insertAtFront(head, 30);
head = insertAtFront(head, 20);
head = insertAtFront(head,
10);
printf("Doubly linked list: "); displayForward(head);
head = deleteValue(head, 20);
printf("After deleting 20: "); displayForward(head);
// free nodes
while (head) { DNode *t = head;
head = head->next; free(t); }
return 0;
}
15. Binary tree traversals (preorder, inorder, postorder)
#include <stdio.h>
#include <stdlib.h>
typedef struct TNode {
int data;
struct TNode *left, *right;
}
TNode;
TNode* newNode(int val) {
TNode *n = (TNode*)malloc(sizeof(TNode));
n->data = val; n->left =
n->right = NULL; return n;
}
void inorder(TNode *root) {
if (!root) return;
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
void preorder(TNode *root) {
if (!root) return;
printf("%d ", root->data);
preorder(root->left);
preorder(root->right);
}
void postorder(TNode *root)
{
if (!root) return;
postorder(root->left);
postorder(root->right);
printf("%d ", root->data);
}
int main() {
TNode *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
printf("Preorder: "); preorder(root);
printf("\\n");
printf("Inorder: "); inorder(root); printf("\\n");
printf("Postorder: ");
postorder(root); printf("\\n");
return 0;
}