Professional Documents
Culture Documents
What Is Data Structure Exactly 999
What Is Data Structure Exactly 999
There are various types of data structures, each with its own set of rules and
characteristics. Some common data structures include:
1. Organization of Data:
Efficient Storage: Data structures allow for the efficient storage of data, ensuring
that information is organized in a way that enables quick and easy access.
Logical Representation: They provide a logical and hierarchical representation
of data, making it easier for programmers to conceptualize and work with
complex datasets.
2. Data Retrieval and Search:
Fast Retrieval: Well-designed data structures facilitate fast retrieval of data. For
example, using data structures like arrays or hash tables can significantly speed
up the search process.
Search Algorithms: Data structures are closely tied to search algorithms, which
are crucial for finding specific pieces of information within a dataset.
3. Memory Management:
Dynamic Memory Allocation: Data structures allow for dynamic memory
allocation, enabling programs to adapt to changing data sizes during runtime.
Memory Efficiency: They help in utilizing memory efficiently by avoiding
unnecessary storage and reducing memory fragmentation..
4. Algorithm Design:
Algorithm Efficiency: Efficient algorithms often rely on the appropriate choice of
data structures. The same algorithm may have different time complexities based
on the underlying data structures used.
Algorithm Definition
An algorithm is a step-by-step set of instructions or a well-defined computational
procedure that takes an input, performs a sequence of operations, and produces an
output. Essentially, it is a method or a systematic way of solving a problem or
performing a task. Algorithms are used in various fields such as computer science,
mathematics, and engineering, and they play a crucial role in computer programming.
The term "good algorithm" can be subjective and context-dependent. The effectiveness of an
algorithm depends on the specific problem it aims to solve, the constraints of the system it
operates in, and the goals or criteria used to evaluate its performance.
1. Correctness: A good algorithm should produce the correct output for all valid inputs. It
should accurately solve the intended problem.
2. Efficiency: An efficient algorithm accomplishes the task using a reasonable amount of
resources such as time, memory, or energy.
3. Scalability: A good algorithm should be able to handle larger inputs or datasets without
a significant increase in resource requirements.
4. Clarity and Simplicity: A good algorithm is often simple, easy to understand, and well-
organized. Clarity in design and implementation contributes to maintainability
5. Robustness: The algorithm should be able to handle unexpected inputs or edge cases
gracefully, avoiding crashes or incorrect results.
Various Factors that impact on performance
Hardware
Operating system
Compiler
Size of input
Nature of input
Algorithm
1. Hardware:
The physical components of a computer, such as the CPU, RAM, storage, and
GPU, can significantly affect the performance of a program. Faster and more
powerful hardware generally leads to better performance.
2. Operating System:
The choice of the operating system can influence how a program interacts with
the underlying hardware. Different operating systems have different performance
characteristics and may offer various optimizations.
3. Compiler:
The compiler translates source code into machine code that can be executed by
the computer. The efficiency of the compiler and the optimizations it applies can
impact the performance of the resulting executable.
4. Size of Input:
The amount of data or the size of the input can affect how efficiently a program
runs. Some algorithms may have different time or space complexities based on
the size of the input.
5. Nature of Input:
The type of data and its characteristics can also impact performance. For
example, certain algorithms may perform differently on sorted or unsorted data,
6. Algorithm:
The choice of algorithm is crucial. Different algorithms solve problems in different
ways, and their efficiency can vary based on the specific requirements of the task
at hand.
A Linked List is a linear data structure which looks like a chain of nodes, where each
node is a different element. Unlike Arrays, Linked List elements are not stored at a
contiguous location.
It is basically chains of nodes, each node contains information such as data and a pointer
to the next node in the chain. In the linked list there is a head pointer, which points to
the first element of the linked list, and if the list is empty then it simply points to null or
nothing.
Here are a few advantages of a linked list that is listed below, it will help you understand why it
is necessary to know.
Dynamic Data structure: The size of memory can be allocated or de-allocated at run time based
on the operation insertion or deletion.
Ease of Insertion/Deletion: The insertion and deletion of elements are simpler than arrays since
no elements need to be shifted after insertion and deletion, Just the address needed to be
updated.
Efficient Memory Utilization: As we know Linked List is a dynamic data structure the size
increases or decreases as per the requirement, so this avoids the wastage of memory.
Implementation: Various advanced data structures can be implemented using a linked list like a
stack, queue, graph, hash maps, etc.
1. Singly-linked list
Traversal of items can be done in the forward direction only due to the linking of every node to its next
node.
Commonly used operations on Singly Linked List:
Insertion: The insertion operation can be performed in three ways. They are as follows…
Deletion: The deletion operation can be performed in three ways. They are as follows…
Deleting from the Beginning of the list
Deleting from the End of the list
Deleting a Specific Node
Search: It is a process of determining and retrieving a specific node either from the front, the end or
anywhere in the list.
• Make the first node of Linked List linked to the new node
• Remove the head from the original first node of Linked List
• If it do not exists,
• Now shift the original next pointer of given node to the next pointer of new node
• Change the next pointer of last node from NULL to the new node
• Make the next pointer of new node as NULL to show the end of Linked List
3. Make the next of new_node point to the current head of the doubly linked list.
4. Set the previous pointer of this new_node as the previous node of the next_node.
1. If the previous node of the new_node is not NULL, then set the next pointer of this
previous node as new_node.
2. Else, if the prev of new_node is NULL, it will be the new head node.
• Memory efficient: Memory consumption of a linked list is efficient as its size can grow
or shrink dynamically according to our requirements, which means effective memory
utilization hence, no memory wastage.
• Ease of Insertion and Deletion: Insertion and deletion of nodes are easily implemented
in a linked list at any position.
• Implementation: For the implementation of stacks and queues and for the
representation of trees and graphs.
• Accessing a node: Random access is not possible due to dynamic memory allocation.
• Search operation costly: Searching for an element is costly and requires O(n) time
complexity.
• In web browsers and editors, doubly linked lists can be used to build a forwards and
backward navigation button.
• A circular doubly linked list can also be used for implementing data structures like
Fibonacci heaps.
• To implement the stack, it is required to maintain the pointer to the top of the stack, which is
the last element to be inserted because we can access the elements only on the top of the
stack.
• This strategy states that the element that is inserted last will come out first. You can take a pile
of plates kept on top of each other as a real-life example. The plate which we put last is on the
top and since we remove the plate that is at the top, we can say that the plate that was put last
comes out first.
• In order to make manipulations in a stack, there are certain operations provided to us.
Begin
if stack is full
Return
Endif
else
increment top
stack[top] assign value
end else
end procedure
Pop:
Algorithm for pop:
Begin
if stack is empty
return
endif
else
store value of stack[top]
decrement top
return value
end else
end procedure
Top:
Returns the top element of the stack.
isEmpty:
Returns true if the stack is empty, else false.
Algorithm for isEmpty:
Begin
if top < 1
return true
else
return false
end procedure
Types of Stacks:
• Fixed Size Stack: As the name suggests, a fixed size stack has a fixed size and cannot grow or
shrink dynamically. If the stack is full and an attempt is made to add an element to it, an
overflow error occurs. If the stack is empty and an attempt is made to remove an element from
it, an underflow error occurs.
• Dynamic Size Stack: A dynamic size stack can grow or shrink dynamically. When the stack is full,
it automatically increases its size to accommodate the new element, and when the stack is
empty, it decreases its size. This type of stack is implemented using a linked list, as it allows for
easy resizing of the stack.
Implementation of Stack:
• A stack can be implemented using an array or a linked list
Array implementation:
Advantages:
Disadvantages:
Advantages:
1. Random Access: Arrays provide constant-time access to elements based on their index.
This means you can directly access any element in the array by using its position, which
makes retrieval efficient.
2. Memory Efficiency: Arrays have a contiguous memory allocation, which makes them
memory-efficient. Elements are stored in adjacent memory locations, allowing for easy
traversal.
3. Simple Implementation: Arrays are simple and straightforward to implement. They are
supported by most programming languages and are often part of the core language
features.
4. Predictable Performance: Due to constant-time access and straightforward memory
organization, the performance characteristics of arrays are predictable and generally
reliable.
Disadvantages:
1. Fixed Size: The size of an array is fixed at the time of declaration, which can lead to
inefficiencies when the number of elements is not known in advance or changes
dynamically. This limitation is addressed by dynamic arrays or other data structures like
linked lists.
2. Insertion and Deletion Overhead: Inserting or deleting elements in an array, especially
in the middle, can be inefficient. This is because existing elements may need to be
shifted to accommodate the new element or fill the gap left by the deleted one.
3. Wasted Memory: If the array size is larger than the number of elements it contains,
there is wasted memory. This is particularly significant if memory is a critical resource.
4. Sequential Storage Requirement: Elements in an array must be stored in contiguous
memory locations. This requirement can limit the efficiency of memory utilization,
especially in scenarios where memory is fragmented.
5. Lack of Dynamic Resizing: Traditional arrays have a fixed size, and resizing them
requires creating a new array and copying elements. This operation can be time-
consuming, especially for large arrays.
1. Dynamic Size:
Linked lists can easily grow or shrink in size during program execution, as
memory can be allocated or deallocated dynamically.
2. Easy Insertion and Deletion:
Inserting or deleting elements in a linked list is efficient and can be done in
constant time, given a reference to the node where the operation is to be
performed.
3. No Wastage of Memory:
Linked lists do not waste memory like arrays do when there is a need to allocate a
fixed size in advance. Memory is allocated as needed.
4. No Need for Contiguous Memory:
Unlike arrays, linked lists do not require contiguous memory. Each element can
be located at a different memory location, allowing for more efficient memory
utilization.
5. Ease of Implementation:
Implementing a basic linked list is simpler than managing arrays, especially when
it comes to resizing or adding/removing elements.
Disadvantages:
• We define a queue to be a list in which all additions to the list are made at one end, and
all deletions from the list are made at the other end. The element which is first pushed
into the order, the delete operation is first performed on that.
• Position of the entry in a queue ready to be served, that is, the first entry that will be removed
from the queue, is called the front of the queue(sometimes, head of the queue), similarly, the
position of the last entry in the queue, that is, the one most recently added, is called the rear (or
the tail) of the queue
Characteristics of Queue:
1. FIFO (First In, First Out): The foremost characteristic of a queue is that it follows the
FIFO principle. The first element added to the queue is the first one to be removed.
2. Enqueue: Elements are added to the rear or back of the queue. This operation is often
called "enqueue."
3. Dequeue: Elements are removed from the front or head of the queue. This operation is
often called "dequeue."
4. Single-ended: A queue is single-ended, meaning that operations are performed at only
one end of the data structure.
5. Dynamic Size: Queues can dynamically adjust their size to accommodate varying
amounts of data.
6. Limited Access: Unlike arrays or linked lists, where you can access elements at any
position, queues allow access to only the front and rear elements.
• enqueue(): Inserts an element at the end of the queue i.e. at the rear end.
• dequeue(): This operation removes and returns an element that is at the front end of the queue.
• front(): This operation returns the element at the front end without removing it.
• rear(): This operation returns the element at the rear end without removing it.
• size(): This operation returns the size of the queue i.e. the total number of elements it contains.
Enqueue():
Enqueue() operation in Queue adds (or stores) an element to the end of the queue.
The following steps should be taken to enqueue (insert) data into a queue:
• Step 3: If the queue is not full, increment the rear pointer to point to the next empty space.
• Step 4: Add the data element to the queue location, where the rear is pointing.
• Step 2: If the queue is empty, return the underflow error and exit.
• Step 3: If the queue is not empty, access the data where the front is pointing.
• Step 4: Increment the front pointer to point to the next available data element.
Simple Queue:
• Simple queue also known as a linear queue is the most basic version of a queue.
• Insertion of an element i.e. the Enqueue operation takes place at the rear end and removal of an
element i.e. the Dequeue operation takes place at the front end.
• Here problem is that if we pop some item from front and then rear reach to the capacity of the
queue and although there are empty spaces before front means the queue is not full but as per
condition in isFull() function, it will show that the queue is full then. To solve this problem we
use circular queue.
Circular Queue:
• The working of a circular queue is similar to the linear queue except for the fact that the last
element is connected to the first element.
• Its advantage is that the memory is utilized in a better way. This is because if there is an empty
space i.e. if no element is present at a certain position in the queue, then an element can be
easily added at that position using modulo capacity(%n).
• Its specialty is that it arranges the elements in a queue based on some priority. The priority can
be something where the element with the highest value has the priority so it creates a queue
with decreasing order of values. The priority can also be such that the element with the lowest
value gets the highest priority so in turn it creates a queue with increasing order of values.
• Dequeue:
• As the name suggests double ended, it means that an element can be inserted or removed from
both ends of the queue, unlike the other queues in which it can be done only from one end.
• Because of this property, it may not obey the First In First Out property.
Applications of Queue:
• Queue is used when things don’t have to be processed immediately, but have to be processed in
First In First Out order like Breadth First Search. This property of Queue makes it also useful in
following kind of scenarios.
• When a resource is shared among multiple consumers. Examples include CPU scheduling, Disk
Scheduling.
• When data is transferred asynchronously (data not necessarily received at same rate as sent)
between two processes. Examples include IO Buffers, pipes, file IO, etc.
• Queue can be used as an essential component in various other data structures.
Stack:
A stack is a linear data structure in which elements can be inserted and deleted only from one
side of the list, called the top. A stack follows the LIFO (Last In First Out) principle, i.e., the
element inserted at the last is the first element to come out. The insertion of an element into
the stack is called push operation, and the deletion of an element from the stack is called pop
operation. In stack, we always keep track of the last element present in the list with a pointer
called top.
Queue :
Queue is a linear data structure in which elements can be inserted only from one side of the list
called rear, and the elements can be deleted only from the other side called the front. The
queue data structure follows the FIFO (First In First Out) principle, i.e. the element inserted at
first in the list, is the first element to be removed from the list. The insertion of an element in a
queue is called an enqueue operation and the deletion of an element is called a dequeue
operation. In queue, we always maintain two pointers, one pointing to the element which was
inserted at the first and still present in the list with the front pointer and the second pointer
pointing to the element inserted at the last with the rear pointer.
Difference between Stack and Queue Data Structures
Stacks Queues
A stack is a data structure that stores a collection of elements, with A queue is a data structure that stores a collection of elements, with
operations to push (add) and pop (remove) elements from the top of the operations to enqueue (add) elements at the back of the queue, and
stack. dequeue (remove) elements from the front of the queue.
Stacks are based on the LIFO principle, i.e., the element inserted at the last, Queues are based on the FIFO principle, i.e., the element inserted at the
is the first element to come out of the list. first, is the first element to come out of the list.
Stacks are often used for tasks that require backtracking, such as parsing Queues are often used for tasks that involve processing elements in a
expressions or implementing undo functionality. specific order, such as handling requests or scheduling tasks.
Insertion and deletion in queues takes place from the opposite ends of the
Insertion and deletion in stacks takes place only from one end of the list
list. The insertion takes place at the rear of the list and the deletion takes
called the top.
place from the front of the list.
Insert operation is called push operation. Insert operation is called enqueue operation.
Can be considered as a vertical collection visual. Can be considered as a horizontal collection visual.
Applications of stack:
1. Function Call Management:
Stacks are used to manage function calls in a program. When a function is called,
its local variables and execution context are pushed onto the stack.
2. Expression Evaluation:
Stacks are employed in the evaluation of expressions, especially those involving
parentheses. Operators and operands are pushed onto the stack,
3. Undo Mechanisms:
Many applications, such as text editors or graphic design software, use stacks to
implement undo mechanisms.
4. Browser History:
Web browsers use stacks to maintain the history of visited pages. Each new page
visited is pushed onto the stack.
5. Parsing and Syntax Checking:
Stacks are employed in parsing and syntax checking of programming languages.
6. Memory Management:
The call stack is used for managing the execution of programs and plays a crucial
role in memory allocation and deallocation.
7. Undo and Redo in Software:
Similar to undo mechanisms, redo functionality can also be implemented using
stacks.