0% found this document useful (0 votes)
6 views8 pages

Introduction to Data Structures

Uploaded by

rabbaswpc
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
Download as docx, pdf, or txt
0% found this document useful (0 votes)
6 views8 pages

Introduction to Data Structures

Uploaded by

rabbaswpc
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1/ 8

Introduction to Data Structures

What is a Data Structure?

A data structure is a way of organizing and storing data so that it can be accessed and
modified efficiently. It determines the way data is arranged in memory and how operations
such as retrieval, insertion, and deletion are performed.

Types of Data Structures

Data structures can be broadly classified into two types:

1. Primitive Data Structures: These are the basic building blocks for data
manipulation. Examples include:
o Integer
o Float
o Character
o Boolean
2. Non-Primitive Data Structures: These are more complex structures derived from
primitive types. They are further divided into:
o Linear Data Structures: Data elements are arranged sequentially. Examples:
 Arrays
 Linked Lists
 Stacks
 Queues
o Non-Linear Data Structures: Data elements are arranged hierarchically or
non-sequentially. Examples:
 Trees
 Graphs
o Hashing: Organizes data using hash functions for efficient searching.

Elementary Data Organization

 Data: A collection of raw facts and figures.


 Records: A group of related fields (e.g., a student’s record includes name, roll
number, and marks).
 Fields: Individual pieces of data (e.g., a student’s name).
 Files: A collection of records stored on a disk.

Data Structure Operations


Common operations performed on data structures include:

1. Insertion: Adding a new element to the data structure.


2. Deletion: Removing an existing element from the data structure.
3. Traversal: Accessing each element of the data structure exactly once to process it.
4. Searching: Finding the location of an element in the data structure.
5. Sorting: Arranging elements in a specific order (e.g., ascending or descending).
Analysis of an Algorithm
The efficiency of an algorithm is determined by analyzing its:

1. Time Complexity: The amount of time taken to complete the algorithm as a function
of the input size.
2. Space Complexity: The amount of memory required to execute the algorithm.

Asymptotic Notations

 Big-O Notation (O): Represents the worst-case time complexity.


 Omega Notation (Ω): Represents the best-case time complexity.
 Theta Notation (Θ): Represents the average-case time complexity.

Time-Space Trade-off

There is often a trade-off between time and space in algorithms. For instance:

 Time-efficient algorithms may require more memory.


 Space-efficient algorithms may take more time to execute.

Searching Algorithms
Linear Search

 Definition: A simple method that checks every element in the array sequentially until
the desired element is found.
 Time Complexity: O(n)

Algorithm

void linearSearch(int arr[], int n, int key) {


for (int i = 0; i < n; i++) {
if (arr[i] == key) {
printf("Element found at index %d\n", i);
return;
}
}
printf("Element not found\n");
}

Binary Search

 Definition: A more efficient method that works on sorted arrays by repeatedly


dividing the search interval in half.
 Time Complexity: O(log n)

Algorithm

void binarySearch(int arr[], int n, int key) {


int low = 0, high = n - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (arr[mid] == key) {
printf("Element found at index %d\n", mid);
return;
} else if (arr[mid] < key) {
low = mid + 1;
} else {
high = mid - 1;
}
}
printf("Element not found\n");
}

Summary
 Data structures help in organizing and storing data efficiently.
 Operations like insertion, deletion, and traversal are essential.
 Algorithm analysis uses asymptotic notations to measure efficiency.
 Searching algorithms like linear and binary search have different use cases and
complexities.

1. Array

Insertion:

c
Copy code
#include <stdio.h>

void insert(int arr[], int *n, int value, int index) {


for (int i = *n; i > index; i--) {
arr[i] = arr[i - 1];
}
arr[index] = value;
(*n)++;
}

void printArray(int arr[], int n) {


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

int main() {
int arr[10] = {1, 2, 3, 4, 5};
int n = 5;

insert(arr, &n, 99, 2); // Insert 99 at index 2


printArray(arr, n); // Print array
return 0;
}

Deletion:
c
Copy code
#include <stdio.h>

void delete(int arr[], int *n, int index) {


for (int i = index; i < *n - 1; i++) {
arr[i] = arr[i + 1];
}
(*n)--;
}

void printArray(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};
int n = 5;

delete(arr, &n, 2); // Delete element at index 2


printArray(arr, n); // Print array
return 0;
}

Traversal:

c
Copy code
#include <stdio.h>

void printArray(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};
int n = 5;

printArray(arr, n); // Print array


return 0;
}

2. Stack

Insertion (Push) & Traversal:

c
Copy code
#include <stdio.h>
#define MAX 5

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

void push(int value) {


if (top == MAX - 1) {
printf("Stack Overflow\n");
} else {
stack[++top] = value;
}
}

void traverse() {
if (top == -1) {
printf("Stack is empty\n");
} else {
for (int i = top; i >= 0; i--) {
printf("%d ", stack[i]);
}
printf("\n");
}
}

int main() {
push(10);
push(20);
push(30);
traverse(); // Print stack
return 0;
}

Deletion (Pop):

c
Copy code
#include <stdio.h>
#define MAX 5

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

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

int main() {
push(10);
push(20);
push(30);
printf("Popped: %d\n", pop()); // Remove top element
return 0;
}

3. Queue
Insertion (Enqueue) & Traversal:

c
Copy code
#include <stdio.h>
#define MAX 5

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

void enqueue(int value) {


if (rear == MAX - 1) {
printf("Queue Overflow\n");
} else {
if (front == -1) {
front = 0;
}
queue[++rear] = value;
}
}

void traverse() {
if (front == -1) {
printf("Queue is empty\n");
} else {
for (int i = front; i <= rear; i++) {
printf("%d ", queue[i]);
}
printf("\n");
}
}

int main() {
enqueue(10);
enqueue(20);
enqueue(30);
traverse(); // Print queue
return 0;
}

Deletion (Dequeue):

c
Copy code
#include <stdio.h>
#define MAX 5

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

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

int main() {
enqueue(10);
enqueue(20);
enqueue(30);
printf("Dequeued: %d\n", dequeue()); // Remove front element
return 0;
}

4. Linked List

Insertion & Traversal:

c
Copy code
#include <stdio.h>
#include <stdlib.h>

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

void insert(struct Node** head, int value) {


struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = *head;
*head = newNode;
}

void traverse(struct Node* head) {


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

int main() {
struct Node* head = NULL;
insert(&head, 10);
insert(&head, 20);
insert(&head, 30);
traverse(head); // Print list
return 0;
}

Deletion:

c
Copy code
#include <stdio.h>
#include <stdlib.h>

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

void delete(struct Node** head, int value) {


struct Node* temp = *head, *prev = NULL;
if (temp != NULL && temp->data == value) {
*head = temp->next;
free(temp);
return;
}
while (temp != NULL && temp->data != value) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) return;
prev->next = temp->next;
free(temp);
}

void traverse(struct Node* head) {


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

int main() {
struct Node* head = NULL;
insert(&head, 10);
insert(&head, 20);
insert(&head, 30);
traverse(head); // Print list
delete(&head, 20); // Delete element 20
traverse(head); // Print list after deletion
return 0;
}

You might also like