DSunit 1 Notes
DSunit 1 Notes
Data structure is a way of storing and organizing data efficiently such that the required
operations on them can be performed efficiently with respect to time as well as
memory. Simply, Data Structure are used to reduce complexity (mostly the time
complexity) of the code.
or
Data Structure:
A data structure is a collection of data type 'values' which are stored and organized
in such a way that it allows for efficient access and modification.
Or
Data structure:
A data structure is a technique of storing and organizing the data in such a way that the
data can be utilized in an efficient manner. In computer science , a data structure is
designed in such a way that it can work with various algorithms.
Data structures can be two types:
1. Static Data Structure
2. Dynamic Data Structure
What is a Static Data structure?
In Static data structure the size of the structure is fixed. The content of the data
structure can be modified but without changing the memory space allocated to it.
Static Data structure has fixed memory size whereas in Dynamic Data Structure, the
size can be randomly updated during run time. Thus dynamic data structure
considered efficient with respect to memory complexity of the code. Static Data
Structure provides easier access to elements with respect to dynamic data structure.
Unlike static data structures, dynamic data structures are flexible.
Use of Dynamic Data Structure in Competitive Programming
In competitive programming the constraints on memory limit is not much high and we
cannot exceed the memory limit. Given higher value of the constraints we cannot
allocate a static data structure of that size so Dynamic Data Structures can be useful.
The types of linear data structures are Array, Queue, Stack, Linked List.
o Array: An array consists of data elements of a same data type. For example, if
we want to store the roll numbers of 10 students, so instead of creating 10
integer type variables, we will create an array having size 10. Therefore, we
can say that an array saves a lot of memory and reduces the length of the code.
o Stack: It is linear data structure that uses the LIFO (Last In-First Out) rule in
which the data added last will be removed first. The addition of data element
in a stack is known as a push operation, and the deletion of data element form
the list is known as pop operation.
o Queue: It is a data structure that uses the FIFO rule (First In-First Out). In this
rule, the element which is added first will be removed first. There are two
terms used in the queue front end and rear The insertion operation performed
at the back end is known ad enqueue, and the deletion operation performed at
the front end is known as dequeue.
o Linked list: It is a collection of nodes that are made up of two parts, i.e., data
element and reference to the next node in the sequence.
o
Non-linear data structure
A non-linear data structure is also another type of data structure in which the data
elements are not arranged in a contiguous manner. As the arrangement is
nonsequential, so the data elements cannot be traversed or accessed in a single run. In
the case of linear data structure, element is connected to two elements (previous and
the next element), whereas, in the non-linear data structure, an element can be
connected to more than two elements.
Trees and Graphs are the types of non-linear data structure.
o Tree
It is a non-linear data structure that consists of various linked nodes. It has a hierarchical
tree structure that forms a parent-child relationship. The diagrammatic representation
of a tree data structure is shown below:
For example, the posts of employees are arranged in a tree data structure like managers,
officers, clerk. In the above figure, A represents a manager, B and C represent the
officers, and other nodes represent the clerks.
o Graph
A graph is a non-linear data structure that has a finite number of vertices and edges, and
these edges are used to connect the vertices. The vertices are used to store the data
elements, while the edges represent the relationship between the vertices. A graph is
used in various real-world problems like telephone networks, circuit networks, social
networks like LinkedIn, Facebook. In the case of facebook, a single user can be
considered as a node, and the connection of a user with others is known as edges.
1)Singly linked list : Singly linked list is a collection of nodes with each node having a
data part and a pointer pointing to the next node.
Representation
2) Double linked list: Doubly linked list is a collection of nodes with each node having a
data part and a left pointer pointing to the next node and right pointer pointing to the
right node
Null 10 20 30 Null
4. Circular double linked list: Last node next contain address of first node and first node prev
contain address of last node
SINGLY LINKED LIST
Singly linked list is a collection of nodes with each node having a data part and a pointer
pointing to the next node.
Representation of node
Data Link/next
Node
❖ Node consists of 2 parts
Data Link
❖ The link field always point to the next node in the list
❖ The link field of the last node is null
Node(int d)
{
data=d;
next=NULL;
}
};
In a the above singly-linked list, every element contains some data and a link to the next
element. The elements of a linked list are called the nodes.
A node has two fields i.e. data and next. The data field contains the data being stored
in that specific node. It cannot just be a single variable. There may be many
variables presenting the data section of a node.
The next field contains the address of the next node. So this is the place where the link
between nodes is established.
Basic operations performed on SLL are
1. Insertion
2. Deletion
Insertion
Inserting a new node in the linked list is called insertion.
A new node is created and inserted in the linked list.
There are three cases considered while inserting a node:
1. Insertion at the start/beginning
2. Insertion at the end
3. Insertion at a particular position
Insertion at the Start/Beginning
1. New node should be connected to the first node, which means the head. This
can be achieved by putting the address of the head in the next field of the
new node.
2. New node should be considered as a head. It can be achieved by declaring
head equals to a new node.
Algorithm
a. Get the new node
Node *nn = new Node(d); //nn means new node
b. Put the address of the head in the next field of the new node.
nn->next=hptr;
// C++ Code
void addatbeg(int x)
{
Node *nn=new Node(x);
if(nn==NULL)
{
cout<<"Unable to create node\n";
return;
}
nn->next=hptr;
hptr=nn;
Algorithm
Step 1: Get the new node
Node *temp= new Node(d);
Step 2: If the list is empty then head point to new node.
hptr = temp;
Step 3: If the list is not empty then traverse the list till last node found
a. Get first node address in temp
b. Move to last node till last node next equal to NULL
c. Make last node next hold address of new node
// C++ Code
void create(int d)
{
if(hptr==NULL)
{
Node *temp=new Node(d);
hptr=temp;
}
else
{
Node *temp=hptr;
while(temp->next!=NULL)
{
temp=temp->next;
Now the new node can be inserted between the previous and current node by just
performing two steps:
1. Pass the address of the new node in the next field of the previous node.
2. Pass the address of the current node in the next field of the new node.
We will access these nodes by asking the user at what position he wants to insert the
new node. Now, we will start a loop to reach those specific nodes. We initialized
our current node by the head and move through the linked list. At the end, we would
find two consecutive nodes.
Algorithm
Step 1: Get first node address in temp
temp=hptr
Step 2: Get the new node
Node *nn= new Node(d);
Step 3: Repeat step 4 and 5 till node at specified position found
Step 5: If the list is empty then create node using above create function
Step 6: Make new node point to temp next node and add new node at end of temp
nn->next=temp->next;
temp->next=nn;
while(temp->next->next!=NULL)
temp = temp->next;
temp->next = NULL;
temp->next = temp->next->next;
if(hptr==NULL)
{
cout<<"List is empty\n";
return;
}
Node *temp=hptr,*prev;
while(temp!=NULL)
{
if(temp->data== x)
{
if(temp == hptr)
{
hptr = temp->next;
}
else
{
prev->next=temp->next;
}
cout<<"Node deleted\n";
delete temp;
return;
}
prev=temp;
temp=temp->next;
}
cout<<"Element not found\n";
}
TRAVERSAL(DISPLAY METHOD) :
Displaying the contents of a linked list is very simple. We keep
moving the temp node to the next one and display its contents.
When temp is NULL , we know that we have reached the end of the linked
list so we get out of the while loop.
void display()
{
Node *t=hptr;
while(t!=NULL)
{
cout<<t->data<<"->";
t=t->next;
}
}
Applications of linked list in computer science –
1. Implementation of stacks and queues
2. Implementation of graphs : Adjacency list representation of
graphs is most popular which is uses linked list to store adjacent
vertices.
3. Dynamic memory allocation : We use linked list of free blocks.
4. Maintaining directory of names
5. Performing arithmetic operations on long integers
6. Manipulation of polynomials by storing constants in the node of
linked list
7. representing sparse matrices.
Example
Address of next
node/ NULL
20
A doubly linked list is also a collection of nodes. Each node here consists of a data part and two pointers.
One pointer points to the previous node while the second pointer points to the next node. We can
traverse the list is forward or backward directions.
As in the singly linked list, the doubly linked list also has a head and a tail.
The previous pointer of the head is set to NULL as this is the first node.
The next pointer of the tail node is set to NULL as this is the last node.
3004
3000 head tail
Each node has two pointers, one pointing to the previous node and the other pointing to the next node. Only
the first node (head) has its previous node set to null and the last node (tail) has its next pointer set to
null.
The advantage of doubly linked list over the singly linked list is as the doubly linked list contains two pointers
i.e. previous and next, we can traverse it into the directions forward and backward.
C++ node representation
Class Node
{
Public:
int data;
Node *next;
Node *prev;
Node(int d)
{
int data =d;
next = NULL;
prev= NULL;
}
void display()
{
cout<< data<<endl;
}
};
Basic Operations
Insertion
This operation inserts a new node in the linked list in the following way
Deletion
Deletion operation deletes a node from a given position in the doubly linked list.
• Deletion of the first node – Deletes the first node in the list
• Deletion of the last node – Deletes the last node in the list.
• Deletion of a node given the data – Given the data, the operation matches the data with the
node data in the linked list and deletes that node.
Traversal
Traversal is a technique of visiting each node in the linked list. In a doubly linked list, we have two types of
traversals as we have two pointers with different directions in the doubly linked list.
• Forward traversal – Traversal is done using the next pointer which is in the forward direction.
• Backward traversal – Traversal is done using the previous pointer which is the backward
direction.
Search
Search operation in the doubly linked list is used to search for a particular node in the linked list. For this
purpose, we need to traverse the list until a matching data is found.
Insertion
Insert a node at the front
Insertion of a new node at the front of the list is shown above. As seen, the previous (prev) of new node N is
set to null. Head points to the new node. The next pointer of N now points to N1 and previous of N1 that
was earlier pointing to Null now points to N.
Algorithm
Step 1: If the list is empty then head point to new node.
d. Get the new node
Node *nptr = new Node(d);
e. Make head point to new node
hptr=temp;
Step 2: If the list is not empty then make previous first node prev point to new node and new
node
next point to previous first node whose address is in head. Now make tail point to new
node
Inserting node at the end of the doubly linked list is achieved by pointing the next pointer of new node N to
null. The previous pointer of N is pointed to N5. The ‘Next’ pointer of N5 is pointed to N.
Algorithm
Step 1: Get the new node
Node *nptr = new Node(d);
Step 2: If the list is empty then head and tail point to new node.
hptr = tptr = nptr;
Step 3: If the list is not empty then make previous last node point to new node and new node
prev
point to previous last node whose address is in tail. Now make tail point to new node
new node
Tail
As shown in the above diagram, when we have to add a node before or after a particular node, we change
the previous and next pointers of the before and after nodes so as to appropriately point to the new
node. Also, the new node pointers are appropriately pointed to the existing nodes.
Algorithm
Step 1: If the list is empty then print “List empty”
Step 2: If the list is not empty then make p hold address of first node
p= hptr
Step 3: repeat step 4 until end of list
Step 4: If node data equal to specified data // specified node becomes previous node
Step 4.1: Get the new node
Node *temp = new Node(d);
Step 4.2: Make new node temp point previous (p) and next node
temp -> next = p -> next;
temp ->prev = p;
Step 4.3: Make next node of previous(p) node to point to temp by its prev
p->next->prev =temp;
Step 4.4: Make previous node to point to temp by its next
p -> next = temp
Step 4.5: Go to step 6
Step 4.5: make p point to next node
p = p -> next;
Step 4.6: Go to step 3
Step 5: Print specified node not found
Step 6: Stop
cout <<"\n"<< afteritem << " not present in the list." << endl;
return;
}
}
Here node with address 400 and data 40 has been added after node containing data value 10
The following steps are followed, to delete a node at the beginning of the list:
Algorithm:
Step 1: If list is empty then display ‘Empty List’ message.
Step 2.1.1: Make head point to second node to make it first node in first node delete list
Here first node with address 100 and data 10 is deleted by making head ((start) point to second node with
address 200. Make second node prev contain NULL i.e. X here in diagram.
The following steps are followed to delete a node at the end of the list:
Algorithm:
Step 2.1: If tptr->data == d // Check given data matches last node data
Step 2.1.1: Make tail point to last second node, to make it last node in last node delete
list
Here last node with address 300 and data 30 is deleted by making tail point to last second node with
address 200. Make second node next from last contain NULL i.e. X
Algorithm:
The following steps are followed, to delete a node from an intermediate position whose data
matches the specified data /search data in the list. Note we go for intermediate node only
after if list is not empty, or specified data not matches first or last node.
Step 2: Repeat step 3 till temp not equal to NULL // search till end of list
Step 3: if temp next node present and next node data matches specified data then
Step 3.1: make temp point to next to next node
Step 5: Stop
Figure shows deleting a node that matches specified data at intermediate position other than
beginning and end from a double linked list
To display the information, you have to traverse the list, node by node from the first node, until
the end of the list is reached. The function forward_display is used for traversing and
displaying the information stored in the list from left to right.
The following steps are followed, to traverse a list from left to right:
Algorithm:
Step 2: If the list is not empty, follow the steps given below:
while(temp!=NULL)
void forward_display(){
Node *temp = hptr;
while(temp!=NULL){
temp->display();
temp = temp->next;
}
}
The function reverse_display is used for traversing and displaying the information stored in the
list from right to left.
The following steps are followed, to traverse a list from right to left
Algorithm:
Step 2: If the list is not empty, follow the steps given below:
while(temp!=NULL)
void reverse_display(){
Node *temp = tptr;
while(temp!=NULL){
temp->display();
temp = temp->prev;
}
}
Doubly Linked list Advantages
1. We can traverse in both directions i.e. from starting to end and as well as from end to
starting. 2. It is easy to reverse the linked list.
3. If we are at a node, then we can go to any node. But in linear linked list, it is not possible to
reach the previous node.
Disadvantages
1. It requires more space per space per node because one extra field is required for pointer
to previous node.
2. Insertion and deletion take more time than linear linked list because more pointer
operations are required than linear linked list.
1. What is Double Linked List?
Double linked list is a sequence of elements in which every element has links to its
previous element and next element in the sequence.
2. Difference
● single linked list ● every node has a link to its next node in the sequence. ● we can
traverse from one node to another node only in one direction ● we can not
traverse back ● double linked list ● every node has a link to its previous node and
next node. ● So, we can traverse forward by using the next field and can traverse
backward by using the previous field
• In a singly linked list, for accessing any node of the linked list,
• we start traversing from the first node. If we are at any node in the middle of the
list, then it is not possible to access nodes that precede the given node.
• This problem can be solved by slightly altering the structure of a singly linked list.
• In a singly linked list, the next part (pointer to next node) is NULL. If we utilize this
link to point to the first node, then we can reach the preceding nodes.
Example:
Why have we taken a pointer that points to the last node instead of the first node?
For the insertion of a node at the beginning, we need to traverse the whole list.
Also, for insertion at the end, the whole list has to be traversed.
then in both cases there won’t be any need to traverse the whole list.
So insertion at the beginning or at the end takes constant time, irrespective of the length of the
list.
1. Insertion
2. Deletion
INSERTION
A node can be added in three ways:
• Insertion in an empty list
Ex:
Code:
void InsertAtBegining(int d)
{
Node *temp = new Node(d);
Code:
void InsertAtEnd(int d)
{
Node *temp = new Node(d);
• store the address of the node next to the last node in temp
temp=temp->next;
}
temp->next=temp->next->next;
}
}
}
Circular Linked List Applications
• It is used in multiplayer games to give a chance to each player to
play the game.