Linked List, Stack, Queue
Linked List, Stack, Queue
1. Dynamic Data Structure: In LinkedList, memory is dynamically allocated to the LinkedList. One
can easily add or remove an element to the LinkedList at runtime. Hence, there is no need for an initial
size.
2. Implementation: LinkedList is a very useful Data Structure that helps implement other Data
Structures like Stacks and Queues.
3. No Memory Wastage: As discussed in the first point, memory is dynamically allocated to the
LinkedList. That is why we can remove the memory which is not in use, and no memory is wasted.
4. Insertion and Deletion: In LinkedList, insertion and deletion operations are efficient compared to
other Data Structures such as Arrays as no shifting of elements is required in the LinkedList. Only the
pointers need to be updated.
5. Versatility: Linked lists can be used to implement a wide range of data structures, including
stacks, queues, associative arrays, and graphs, as well as linked data structures such as trees and hash
tables.
6. Persistence: Linked lists can be used to implement persistent data structures, which are data
structures that can be modified and accessed across multiple program executions. This is because linked
lists can be easily serialized and stored in non-volatile memory.
Doubly-linked list: A doubly linked list is a complex type of linked list in which a node
contains a pointer to the previous as well as the next node in the sequence. Therefore, in a
doubly linked list, a node consists of three parts: node data, pointer to the next node in
sequence (next pointer), pointer to the previous node (previous pointer). A sample node in
a doubly linked list is shown in the figure.
Circular-linked list: A circular Linked list is a unidirectional linked list. Circular Linked
List is a variation of a Linked list in which the first element points to the last element and
the last element points to the first element. Singly Linked List and Doubly Linked List can
be made into circular linked lists.
Circular doubly-linked list
A circular doubly linked list is a mixture of a doubly linked list and a circular linked list.
Like the doubly linked list, it has an extra pointer called the previous pointer, and similar to
the circular linked list, its last node points at the head node. This type of linked list is a
bi-directional list. So, you can traverse it in both directions.
Header-linked List
A header-linked list is a type of linked list that has a header node at the beginning of the
list. In a header-linked list, HEAD points to the header node instead of the first node of the
list. The header node does not represent an item in the linked list. This data part of this
node is generally used to hold any global information about the entire linked list. The next
part of the header node points to the first node in the list.
Depth First Search (DFS): Depth First Search algorithm traverses a graph in a
depth-ward motion and uses a stack to remember to get the next vertex to start a search
when a dead-end occurs in any iteration. DFS uses LIFO (Last In First Out) principle while
using Stack to find the shortest path. DFS is also called Edge Based Traversal because it
explores the nodes along the edge or path. DFS is faster and requires less memory. DFS is
best suited for decision trees.
Adjacency List: An Adjacency list is an array consisting of the address of all the linked
lists. The first node of the linked list represents the vertex and the remaining lists connected
to this node represent the vertices to which this node is connected. This representation can
also be used to represent a weighted graph. The linked list can slightly be changed to even
store the weight of the edge.
Huffman Coding-
Huffman Coding is a famous Greedy Algorithm.
● It is used for the lossless compression of data.
● It uses variable length encoding.
● It assigns variable length codes to all the characters.
● The code length of a character depends on how frequently it occurs in the given text.
● The character which occurs most frequently gets the smallest code.
● The character which occurs least frequently gets the largest code.
● It is also known as Huffman Encoding.
Hashing: Hashing refers to the process of generating a fixed-size output from an input of
variable size using the mathematical formulas known as hash functions. This technique
determines an index or location for the storage of an item in a data structure.
Components of Hashing:
There are majorly three components of hashing:
● Key: A Key can be anything string or integer which is fed as input in the hash
function the technique that determines an index or location for storage of an item in a
data structure.
● Hash Function: The hash function receives the input key and returns the index of an
element in an array called a hash table. The index is known as the hash index.
● Hash Table: A hash table is a data structure that maps keys to values using a special
function called a hash function. Hash stores the data in an associative manner in an
array where each data value has its own unique index.
Collision: The hashing process generates a small number for a big key, so there is a
possibility that two keys could produce the same value. The situation where the newly
inserted key maps to an already occupied, and must be handled using some collision
handling technology.
Applications of Hash Data Structure:
● Hash is used in databases for indexing.
● Hash is used in disk-based data structures.
● In some programming languages like Python, JavaScript hash is used to implement
objects.
Real-Time Applications of Hash Data Structure:
● Hash is used for cache mapping for fast access to the data.
● Hash can be used for password verification.
● Hash is used in cryptography as a message digest.
● Rabin-Karp algorithm for pattern matching in a string.
● Calculating the number of different substrings of a string.
Advantages of Hash Data Structure:
● Hash provides better synchronization than other data structures.
● Hash tables are more efficient than search trees or other data structures
● Hash provides constant time for searching, insertion, and deletion operations on
average.
Disadvantages of Hash Data Structure:
● Hash is inefficient when there are many collisions.
● Hash collisions are practically not avoided for a large set of possible keys.
● Hash does not allow null values.
Infix Notation: Infix expressions are the most usual type of expression. This notation is
typically employed when writing arithmetic expressions by hand. Moreover, in the infix
expression, we place the operator between the two operands it operates on.
For example, the operator “+” appears between the operands A and B in the expression “A
+ B”.
Furthermore, infix expressions can also include parentheses to indicate the order of
operations. In this way, we should observe the operator precedence rules and use
parentheses to clarify the order of operations in expressions in infix notation. Operator
precedence rules specify the operator evaluation order in an expression. So, in an
expression, operators with higher precedence are evaluated before operators with lower
precedence. Some operator precedence rules follow:
● Parentheses: expressions inside parentheses are evaluated first
● Exponentiation: exponents are evaluated next
● Multiplication and division: multiplication and division are evaluated before addition
and subtraction
● Addition and subtraction: finally, addition and subtraction are evaluated last
However if an expression has multiple operators with the same precedence, the evaluation
of those operators occurs from left to right.
Prefix Notation: Prefix expressions, also known as Polish notation, place the operator
before the operands. For example, in the expression “+ A B”, we place the “+” operator
before the operands A and B, as demonstrated in the image next:
We should consider that prefix expressions are evaluated from right to left. Thus, we apply
each operator to its operands as it is encountered.
Postfix Notation: Postfix expressions, also known as reverse Polish notation, where we
place the operator after the operands. For instance, in the expression “A B +”, the “+” we
place the operator after the operands A and B. The figure is next depicts the example:
Hence, we can evaluate postfix expressions from left to right, with each operator being
applied to its operands as encountered.
Comparison of the Expression Notations:
The infix notation is the simplest notation for humans to read and write, but it requires
more complex parsing algorithms for computers due to parentheses and operator
precedence rules. The prefix and postfix notations are computationally efficient and do not
require parentheses or operator precedence tracking. Furthermore, the prefix notation can
easily handle unary operators, while infix and postfix notations require special
handling.The infix notation uses parentheses for function arguments, while the prefix and
postfix notations can use other delimiters. The infix notation is the most usual notation for
writing mathematical expressions, while the prefix and postfix notations are appropriate for
particular applications. Examples of these applications are stack-based algorithms and
programming languages.