122ax042 DS 6-10
122ax042 DS 6-10
122ax042 DS 6-10
BATCH: B
BRANCH: CSE IOT
PRN: 122AX0
Experiment No. 6
Single-linked list
In a singly linked list, each node contains a reference to the next node
in the sequence. Traversing a singly linked list is done in a forward
direction.
OUTPUT:
Conclusion: Through this experiment we have understood the
implementation of Linked List.
Experiment No. 8
The circular linked list is a linked list where all nodes are connected
to form a circle. In a circular linked list, the first node and the last
node are connected to each other which forms a circle. There is no
NULL at the end.
Circular singly linked list: In a circular Singly linked list, the last
node of the list contains a pointer to the first node of the list. We
traverse the circular singly linked list until we reach the same node
where we started. The circular singly linked list has no beginning or
end. No null value is present in the next part of any of the nodes.
And then,
2) Insertion at the end of the list: To insert a node at the end of the
list, follow these steps:
Create a node, say T.
Make T -> next = last ->next;
last -> next = T.
last = T.
Before insertion,
After insertion,
Suppose 12 needs to be inserted after the node has the value 10,
After searching and insertion,
3) Delete any node from the circular linked list: We will be given a
node and our task is to delete that node from the circular linked list.
Algorithm:
Case 1: List is empty.
If the list is empty we will simply return.
The right subtree of node 3 includes a value less than it, hence the
binary tree on the right isn't a binary search tree.
How to Operate a Binary Search Tree in C
A binary search tree can be processed using three fundamental
operations:
Operation 1: Search
We need to locate a particular piece in the data structure in Search.
Because the elements are stored in sorted order in binary search trees,
the searching process is made simpler.
The following is the algorithm for seeking an element in a binary tree:
1. Compare the searchable element to the tree's root node.
2. Return the root node if the value of the element being searched
matches the value of the root node.
3. If the value is not the same, see if it is smaller than the root
element, and if so, navigate to the left subtree.
4. Explore the appropriate subtree if it is greater than the root
element.
5. Return NULL if the element isn't present throughout the entire
tree.
With the aid of an example where we are attempting to search for an
item having a value of 20, let's now explore search operation in a
binary search tree code written in C:
Step 1:
Step 2:
Step 2:
Operation 2: Insert
In a binary search tree, an element is always inserted at the leaf node.
If the element to be inserted is smaller than the root value or the root
node, we start our search operation from the root node and look for an
empty position in the left subtree; otherwise, we look for the empty
location in the right subtree.
The following is the algorithm for adding an element to a binary tree:
C Code:
1. if node == NULL
2. return creatingNode(data)
3. if (data < node -> data)
4. node -> left = insert(node -> left, data)
5. else if (data > node -> data)
6. node -> right = insert(node -> right, data)
7. return node
Now that we have a specific instance where we are trying to insert an
item with the value 65, let's examine how insertion works in a binary
search tree:
Operation 3: Deletion
A node from the binary search tree must be deleted during the
deletion operation without violating any of its attributes. Deletion
may happen in one of three situations:
1. Leaf node is the first node to be eliminated.
The simplest scenario for removing a node from a binary search tree
is this one. Here, we'll swap out the leaf node for NULL and release
the space that was allotted.
With the aid of an example that shows us to delete the node with a
value of 90, we can better comprehend the deletion process in a
binary search tree.
2. The deleted node has just one child node.
In this instance, the target node will be replaced with its child, which
will then be deleted. As a result, the value to be erased will now be
present in the child node. Therefore, to release the space allotted, we
will simply replace the child node with NULL.
In the example below, a node with a value of 79 must be eliminated.
Since this node has just one child, 55 will be used in its place.
In the above graph, minimum path 'P' can be found by using the BFS
that will start from Node A and end at Node E. The algorithm uses
two queues, namely QUEUE1 and QUEUE2. QUEUE1 holds all the
nodes that are to be processed, while QUEUE2 holds all the nodes
that are processed and deleted from QUEUE1.
Now, let's start examining the graph starting from Node A.
Step 1 - First, add A to queue1 and NULL to queue2.
1. QUEUE1 = {A}
2. QUEUE2 = {NULL}
Step 2 - Now, delete node A from queue1 and add it into queue2.
Insert all neighbors of node A to queue1.
1. QUEUE1 = {B, D}
2. QUEUE2 = {A}
Step 3 - Now, delete node B from queue1 and add it into queue2.
Insert all neighbors of node B to queue1.
1. QUEUE1 = {D, C, F}
2. QUEUE2 = {A, B}
Step 4 - Now, delete node D from queue1 and add it into queue2.
Insert all neighbors of node D to queue1. The only neighbor of Node
D is F since it is already inserted, so it will not be inserted again.
1. QUEUE1 = {C, F}
2. QUEUE2 = {A, B, D}
Step 5 - Delete node C from queue1 and add it into queue2. Insert all
neighbors of node C to queue1.
1. QUEUE1 = {F, E, G}
2. QUEUE2 = {A, B, D, C}
Step 5 - Delete node F from queue1 and add it into queue2. Insert all
neighbors of node F to queue1. Since all the neighbors of node F are
already present, we will not insert them again.
1. QUEUE1 = {E, G}
2. QUEUE2 = {A, B, D, C, F}
Step 6 - Delete node E from queue1. Since all of its neighbors have
already been added, so we will not insert them again. Now, all the
nodes are visited, and the target node E is encountered into queue2.
1. QUEUE1 = {G}
2. QUEUE2 = {A, B, D, C, F, E}
Complexity of BFS algorithm
Time complexity of BFS depends upon the data structure used to
represent the graph. The time complexity of BFS algorithm
is O(V+E), since in the worst case, BFS algorithm explores every
node and edge. In a graph, the number of vertices is O(V), whereas
the number of edges is O(E).
The space complexity of BFS can be expressed as O(V), where V is
the number of vertices.’
Algorithm
Step 1: SET STATUS = 1 (ready state) for each node in G
Step 2: Push the starting node A on the stack and set its STATUS = 2
(waiting state)
Step 3: Repeat Steps 4 and 5 until STACK is empty
Step 4: Pop the top node N. Process it and set its STATUS = 3
(processed state)
Step 5: Push on the stack all the neighbors of N that are in the ready
state (whose STATUS = 1) and set their STATUS = 2 (waiting state)
[END OF LOOP]
Step 6: EXIT
Pseudocode
1. DFS(G,v) ( v is the vertex where the search starts )
2. Stack S := {}; ( start with an empty stack )
3. for each vertex u, set visited[u] := false;
4. push S, v;
5. while (S is not empty) do
6. u := pop S;
7. if (not visited[u]) then
8. visited[u] := true;
9. for each unvisited neighbour w of uu
10. push S, w;
11. end if
12. end while
13. END DFS()
Example of DFS algorithm
Now, let's understand the working of the DFS algorithm by using an
example. In the example given below, there is a directed graph having
7 vertices.
Now, let's start examining the graph starting from Node H.
Step 1 - First, push H onto the stack.
1. STACK: H
Step 2 - POP the top element from the stack, i.e., H, and print it. Now,
PUSH all the neighbors of H onto the stack that are in ready state.
1. Print: H]STACK: A
Step 3 - POP the top element from the stack, i.e., A, and print it. Now,
PUSH all the neighbors of A onto the stack that are in ready state.
1. Print: A
2. STACK: B, D
Step 4 - POP the top element from the stack, i.e., D, and print it. Now,
PUSH all the neighbors of D onto the stack that are in ready state.
1. Print: D
2. STACK: B, F
Step 5 - POP the top element from the stack, i.e., F, and print it. Now,
PUSH all the neighbors of F onto the stack that are in ready state.
1. Print: F
2. STACK: B
Step 6 - POP the top element from the stack, i.e., B, and print it. Now,
PUSH all the neighbors of B onto the stack that are in ready state.
1. Print: B
2. STACK: C
Step 7 - POP the top element from the stack, i.e., C, and print it. Now,
PUSH all the neighbors of C onto the stack that are in ready state.
1. Print: C
2. STACK: E, G
Step 8 - POP the top element from the stack, i.e., G and PUSH all the
neighbors of G onto the stack that are in ready state.
1. Print: G
2. STACK: E
Step 9 - POP the top element from the stack, i.e., E and PUSH all the
neighbors of E onto the stack that are in ready state.
1. Print: E
2. STACK:
Now, all the graph nodes have been traversed, and the stack is empty.
Complexity of Depth-first search algorithm
The time complexity of the DFS algorithm is O(V+E), where V is the
number of vertices and E is the number of edges in the graph.
The space complexity of the DFS algorithm is O(V).
BFS:
OUTPUT OF BFS :
DFS:
OUTPUT OF DFS:
Conclusion: Through this experiment we have understood the
implementation of Graph Traversal.