0% found this document useful (0 votes)
40 views

Linear Data Structures

Uploaded by

MEENU
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views

Linear Data Structures

Uploaded by

MEENU
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 16

Linear data structures

Linear data structures are types of data structures where data elements are arranged
sequentially, one after the other. Each element is connected to its previous and next
element in a single level, forming a linear sequence. Here are some common linear data
structures:

1. Array

 Description: A collection of elements identified by index or key, where each


element is of the same data type.
 Operations: Access (random access via index), insertion, deletion.
 Advantages: Fast access time if the index is known.
 Disadvantages: Fixed size, insertion, and deletion can be costly as elements need
to be shifted.

2. Linked List

 Description: A sequence of elements, called nodes, where each node contains


data and a reference (or link) to the next node in the sequence.
 Types:
o Singly Linked List: Each node points to the next node.
o Doubly Linked List: Each node points to both the next and the previous
node.
o Circular Linked List: The last node points back to the first node.
 Operations: Traversal, insertion, deletion.
 Advantages: Dynamic size, easy insertion, and deletion.
 Disadvantages: No random access, extra memory for storing pointers.

3. Stack

 Description: A collection of elements that follows the Last In, First Out (LIFO)
principle.
 Operations:
o Push: Add an element to the top of the stack.
o Pop: Remove the top element from the stack.
o Peek: Retrieve the top element without removing it.
 Advantages: Easy to implement, useful for recursive algorithms.
 Disadvantages: Limited access to elements (only the top element can be
accessed).

4. Queue

 Description: A collection of elements that follows the First In, First Out (FIFO)
principle.
 Types:
o Simple Queue: Basic FIFO structure.
o Circular Queue: The last position is connected back to the first position to
make a circle.
o Priority Queue: Elements are processed based on priority.
o Deque (Double-Ended Queue): Elements can be added or removed from
both ends.
 Operations:
o Enqueue: Add an element to the end of the queue.
o Dequeue: Remove an element from the front of the queue.
o Front: Retrieve the front element without removing it.
o Rear: Retrieve the last element without removing it.
 Advantages: Suitable for scheduling and managing tasks in order.
 Disadvantages: Limited access to elements (only front and rear).

Applications of Linear Data Structures

 Arrays: Used in implementing other data structures like heaps, hash tables, etc.
 Linked Lists: Used in dynamic memory allocation, implementing other data
structures like stacks, queues, etc.
 Stacks: Used in expression evaluation, syntax parsing, backtracking algorithms,
etc.
 Queues: Used in scheduling algorithms, managing resources in computing
environments, breadth-first search in graphs, etc.

These linear data structures form the foundation of more complex data structures and
algorithms, playing a crucial role in computer science and software engineering.

Detailed Description of Arrays


Definition: An array is a collection of elements, all of the same type, stored in
contiguous memory locations. Each element in an array is identified by an index.

Characteristics:

 Fixed Size: The size of an array is defined when it is created and cannot be
changed.
 Random Access: Elements can be accessed directly using their index.
 Homogeneous Elements: All elements in

Detailed Description of Arrays

Definition: An array is a collection of elements, all of the same type, stored in


contiguous memory locations. Each element in an array is identified by an index.

Characteristics:
 Fixed Size: The size of an array is defined when it is created and cannot be
changed.
 Random Access: Elements can be accessed directly using their index.
 Homogeneous Elements: All elements in the array are of the same data type.
 Contiguous Memory Allocation: Elements are stored in contiguous memory
locations.

Example of an Array

Consider an array of integers:

plaintext
Copy code
Index: 0 1 2 3 4
Value: 10 20 30 40 50

 The element at index 0 is 10.


 The element at index 1 is 20.
 The element at index 2 is 30.
 The element at index 3 is 40.
 The element at index 4 is 50.

Common Operations on Arrays

1. Accessing Elements:
o Algorithm:
1. Read the index of the element to be accessed.
2. Return the element at the specified index.
o Example:

python
Copy code
arr = [10, 20, 30, 40, 50]
index = 2
element = arr[index] # element = 30

2. Updating Elements:
o Algorithm:
1. Read the index of the element to be updated.
2. Read the new value.
3. Update the element at the specified index with the new value.
o Example:

python
Copy code
arr = [10, 20, 30, 40, 50]
index = 2
new_value = 35
arr[index] = new_value # arr = [10, 20, 35, 40, 50]

3. Inserting Elements:
o Algorithm:
1. Check if there is space in the array.
2. Read the index where the new element is to be inserted.
3. Read the new value.
4. Shift elements from the specified index to the right.
5. Insert the new element at the specified index.
o Example:

python
Copy code
arr = [10, 20, 30, 40, 50]
index = 2
new_value = 25
arr.insert(index, new_value) # arr = [10, 20, 25, 30, 40, 50]

4. Deleting Elements:
o Algorithm:
1. Read the index of the element to be deleted.
2. Shift elements from the specified index to the left.
3. Reduce the size of the array by 1.
o Example:

python
Copy code
arr = [10, 20, 30, 40, 50]
index = 2
arr.pop(index) # arr = [10, 20, 40, 50]

Simple Python Program Demonstrating Array Operations

python
Copy code
def print_array(arr):
print("Array:", arr)

# Initialize an array
arr = [10, 20, 30, 40, 50]
print("Initial Array")
print_array(arr)

# Access an element
index = 2
element = arr[index]
print(f"Element at index {index}: {element}")
# Update an element
new_value = 35
arr[index] = new_value
print(f"Array after updating element at index {index} to {new_value}")
print_array(arr)

# Insert an element
insert_index = 2
new_value = 25
arr.insert(insert_index, new_value)
print(f"Array after inserting {new_value} at index {insert_index}")
print_array(arr)

# Delete an element
delete_index = 2
arr.pop(delete_index)
print(f"Array after deleting element at index {delete_index}")
print_array(arr)

Output:

plaintext
Copy code
Initial Array
Array: [10, 20, 30, 40, 50]
Element at index 2: 30
Array after updating element at index 2 to 35
Array: [10, 20, 35, 40, 50]
Array after inserting 25 at index 2
Array: [10, 20, 25, 35, 40, 50]
Array after deleting element at index 2
Array: [10, 20, 35, 40, 50]

This program demonstrates the basic operations on arrays: accessing, updating,


inserting, and deleting elements.

Detailed Description of Linked Lists

Definition: A linked list is a linear data structure in which elements are not stored in
contiguous memory locations. Instead, each element (called a node) contains a data
part and a reference (or link) to the next node in the sequence.

Types of Linked Lists

1. Singly Linked List: Each node points to the next node in the sequence.
2. Doubly Linked List: Each node points to both the next and the previous node.
3. Circular Linked List: The last node points back to the first node, forming a circle.

Characteristics

 Dynamic Size: The size of a linked list can grow or shrink as needed.
 Ease of Insertion/Deletion: Insertions and deletions can be done easily without
shifting elements, especially at the beginning of the list.
 No Random Access: Elements must be accessed sequentially from the first node.

Components of a Linked List Node

 Data: Stores the data value.


 Next: A pointer/reference to the next node in the sequence.

Example of a Singly Linked List

Consider a singly linked list with three nodes:

plaintext
Copy code
Head -> [10 | Next] -> [20 | Next] -> [30 | None]

Common Operations on Linked Lists

1. Traversal:
o Algorithm:
1. Start from the head node.
2. While the current node is not None:
 Process the data of the current node.
 Move to the next node.
o Example:

python
Copy code
def traverse(head):
current = head
while current:
print(current.data)
current = current.next

2. Insertion:
o Algorithm:
1. Create a new node with the given data.
2. If inserting at the beginning:
 Set the new node's next to the current head.
 Update the head to the new node.
3. If inserting at a given position:
 Traverse to the node after which the new node is to be
inserted.
 Set the new node's next to the next of the current node.
 Update the current node's next to the new node.
o Example:

python
Copy code
def insert(head, data, position):
new_node = Node(data)
if position == 0:
new_node.next = head
head = new_node
return head
current = head
for _ in range(position - 1):
current = current.next
new_node.next = current.next
current.next = new_node
return head

3. Deletion:
o Algorithm:
1. If deleting the head node:
 Update the head to the next node.
2. If deleting a node at a given position:
 Traverse to the node before the one to be deleted.
 Update its next to the next of the node to be deleted.
o Example:

python
Copy code
def delete(head, position):
if position == 0:
head = head.next
return head
current = head
for _ in range(position - 1):
current = current.next
current.next = current.next.next
return head

Simple Python Program Demonstrating Linked List Operations

python
Copy code
class Node:
def __init__(self, data):
self.data = data
self.next = None

class LinkedList:
def __init__(self):
self.head = None

def print_list(self):
current = self.head
while current:
print(current.data, end=" -> ")
current = current.next
print("None")

def insert_at_beginning(self, data):


new_node = Node(data)
new_node.next = self.head
self.head = new_node

def insert_at_position(self, data, position):


new_node = Node(data)
if position == 0:
new_node.next = self.head
self.head = new_node
return
current = self.head
for _ in range(position - 1):
current = current.next
if current is None:
raise IndexError("Position out of bounds")
new_node.next = current.next
current.next = new_node

def delete_at_position(self, position):


if self.head is None:
return
if position == 0:
self.head = self.head.next
return
current = self.head
for _ in range(position - 1):
current = current.next
if current is None or current.next is None:
raise IndexError("Position out of bounds")
current.next = current.next.next
# Initialize the linked list
ll = LinkedList()

# Insert elements
ll.insert_at_beginning(30)
ll.insert_at_beginning(20)
ll.insert_at_beginning(10)
ll.insert_at_position(25, 2)
print("List after insertions:")
ll.print_list()

# Delete an element
ll.delete_at_position(2)
print("List after deletion:")
ll.print_list()

Output:

plaintext
Copy code
List after insertions:
10 -> 20 -> 25 -> 30 -> None
List after deletion:
10 -> 20 -> 30 -> None

This program demonstrates basic operations on a singly linked list: traversing,


inserting, and deleting nodes.

Detailed Description of Stack

Definition: A stack is a linear data structure that follows the Last In, First Out (LIFO)
principle. In a stack, the most recently added element is the first one to be removed.

Characteristics

 LIFO: Last In, First Out order of operations.


 Push: Adding an element to the top of the stack.
 Pop: Removing the element from the top of the stack.
 Peek/Top: Accessing the top element without removing it.
 IsEmpty: Checking if the stack is empty.
 Size: Determining the number of elements in the stack.

Applications of Stacks

 Function Call Management: Managing function calls in programming languages.


 Expression Evaluation: Evaluating expressions (e.g., postfix, prefix notation).
 Backtracking: Implementing algorithms that need to backtrack (e.g., maze
solving).
 Undo Mechanisms: Implementing undo features in text editors and other
applications.

Common Operations on Stacks

1. Push Operation:
o Algorithm:
1. Check if the stack is full (in case of a bounded stack).
2. If not, increment the top index.
3. Add the element at the top position.
o Example:

python
Copy code
stack = []
stack.append(element) # Push element onto stack

2. Pop Operation:
o Algorithm:
1. Check if the stack is empty.
2. If not, access the element at the top position.
3. Decrement the top index.
4. Return the accessed element.
o Example:

python
Copy code
if stack:
element = stack.pop() # Pop element from stack

3. Peek Operation:
o Algorithm:
1. Check if the stack is empty.
2. If not, access the element at the top position without removing it.
o Example:

python
Copy code
if stack:
top_element = stack[-1] # Peek at the top element

4. IsEmpty Operation:
o Algorithm:
1. Check if the stack size is zero.
o Example:
python
Copy code
is_empty = len(stack) == 0 # Check if stack is empty

5. Size Operation:
o Algorithm:
1. Return the size of the stack.
o Example:

python
Copy code
size = len(stack) # Get the size of the stack

Simple Python Program Demonstrating Stack Operations

python
Copy code
class Stack:
def __init__(self):
self.stack = []

def is_empty(self):
return len(self.stack) == 0

def push(self, item):


self.stack.append(item)
print(f"Pushed {item} onto stack")

def pop(self):
if self.is_empty():
print("Stack is empty, cannot pop")
return None
return self.stack.pop()

def peek(self):
if self.is_empty():
print("Stack is empty, cannot peek")
return None
return self.stack[-1]

def size(self):
return len(self.stack)

def print_stack(self):
print("Stack:", self.stack)

# Initialize the stack


stack = Stack()

# Push elements onto the stack


stack.push(10)
stack.push(20)
stack.push(30)
print("Stack after pushing elements:")
stack.print_stack()

# Peek at the top element


top_element = stack.peek()
print(f"Top element: {top_element}")

# Pop an element from the stack


popped_element = stack.pop()
print(f"Popped element: {popped_element}")
print("Stack after popping an element:")
stack.print_stack()

# Check if the stack is empty


is_empty = stack.is_empty()
print(f"Is stack empty? {is_empty}")

# Get the size of the stack


size = stack.size()
print(f"Size of the stack: {size}")

Output:

plaintext
Copy code
Pushed 10 onto stack
Pushed 20 onto stack
Pushed 30 onto stack
Stack after pushing elements:
Stack: [10, 20, 30]
Top element: 30
Popped element: 30
Stack after popping an element:
Stack: [10, 20]
Is stack empty? False
Size of the stack: 2

This program demonstrates the basic operations on a stack: pushing, popping, peeking,
checking if the stack is empty, and determining the size of the stack.

Detailed Description of Queue


Definition: A queue is a linear data structure that follows the First In, First Out (FIFO)
principle. In a queue, the element that is added first will be the first one to be removed.

Characteristics

 FIFO: First In, First Out order of operations.


 Enqueue: Adding an element to the end of the queue.
 Dequeue: Removing the element from the front of the queue.
 Front: Accessing the front element without removing it.
 Rear: Accessing the last element.
 IsEmpty: Checking if the queue is empty.
 Size: Determining the number of elements in the queue.

Types of Queues

1. Simple Queue: Basic FIFO structure.


2. Circular Queue: The last position is connected back to the first position to make
a circle.
3. Priority Queue: Elements are processed based on priority.
4. Deque (Double-Ended Queue): Elements can be added or removed from both
ends.

Applications of Queues

 Scheduling Algorithms: Used in operating systems for task scheduling.


 Resource Management: Managing resources in computing environments.
 Breadth-First Search: Used in graph traversal algorithms.
 Buffering: Used in data buffering (e.g., IO operations, streaming).

Common Operations on Queues

1. Enqueue Operation:
o Algorithm:
1. Check if the queue is full (in case of a bounded queue).
2. If not, add the element to the rear of the queue.
3. Update the rear index.
o Example:

python
Copy code
queue = []
queue.append(element) # Enqueue element to the rear

2. Dequeue Operation:
o Algorithm:
1. Check if the queue is empty.
2. If not, access the element at the front.
3. Remove the element from the front.
4. Update the front index.
o Example:

python
Copy code
if queue:
element = queue.pop(0) # Dequeue element from the front

3. Front Operation:
o Algorithm:
1. Check if the queue is empty.
2. If not, access the element at the front without removing it.
o Example:

python
Copy code
if queue:
front_element = queue[0] # Access the front element

4. IsEmpty Operation:
o Algorithm:
1. Check if the queue size is zero.
o Example:

python
Copy code
is_empty = len(queue) == 0 # Check if queue is empty

5. Size Operation:
o Algorithm:
1. Return the size of the queue.
o Example:

python
Copy code
size = len(queue) # Get the size of the queue

Simple Python Program Demonstrating Queue Operations

python
Copy code
class Queue:
def __init__(self):
self.queue = []

def is_empty(self):
return len(self.queue) == 0
def enqueue(self, item):
self.queue.append(item)
print(f"Enqueued {item} to the queue")

def dequeue(self):
if self.is_empty():
print("Queue is empty, cannot dequeue")
return None
return self.queue.pop(0)

def front(self):
if self.is_empty():
print("Queue is empty, cannot access front")
return None
return self.queue[0]

def size(self):
return len(self.queue)

def print_queue(self):
print("Queue:", self.queue)

# Initialize the queue


queue = Queue()

# Enqueue elements
queue.enqueue(10)
queue.enqueue(20)
queue.enqueue(30)
print("Queue after enqueuing elements:")
queue.print_queue()

# Access the front element


front_element = queue.front()
print(f"Front element: {front_element}")

# Dequeue an element
dequeued_element = queue.dequeue()
print(f"Dequeued element: {dequeued_element}")
print("Queue after dequeuing an element:")
queue.print_queue()

# Check if the queue is empty


is_empty = queue.is_empty()
print(f"Is queue empty? {is_empty}")
# Get the size of the queue
size = queue.size()
print(f"Size of the queue: {size}")

Output:

plaintext
Copy code
Enqueued 10 to the queue
Enqueued 20 to the queue
Enqueued 30 to the queue
Queue after enqueuing elements:
Queue: [10, 20, 30]
Front element: 10
Dequeued element: 10
Queue after dequeuing an element:
Queue: [20, 30]
Is queue empty? False
Size of the queue: 2

This program demonstrates basic operations on a queue: enqueuing, dequeuing,


accessing the front element, checking if the queue is empty, and determining the size of
the queue.

You might also like