- DAA - Discussion
- DAA - Useful Resources
- DAA - Quick Guide
- DAA - Hill Climbing Algorithm
- NP Hard & NP-Complete Classes
- DAA - Cook’s Theorem
- DAA - P and NP Class
- DAA - Vertex Cover
- DAA - Max Cliques
- Deterministic vs. Nondeterministic Computations
- DAA - Sublist Search
- DAA - Fibonacci Search
- DAA - Exponential Search
- DAA - Jump Search
- DAA - Interpolation Search
- DAA - Binary Search
- DAA - Linear Search
- Searching Techniques Introduction
- DAA - Radix Sort
- DAA - Counting Sort
- DAA - Bucket Sort
- DAA - Heap Sort
- DAA - Shell Sort
- DAA - Selection Sort
- DAA - Insertion Sort
- DAA - Bubble Sort
- DAA - Extract Method
- DAA - Heapify Method
- DAA - Insert Method
- DAA - Binary Heap
- Optimal Cost Binary Search Trees
- DAA - Multistage Graph
- DAA - Shortest Paths
- DAA - Spanning Tree
- Travelling Salesperson Approximation Algorithm
- Set Cover Problem
- Vertex Cover Problem
- Approximation Algorithms
- Fisher-Yates Shuffle
- Karger’s Minimum Cut
- Randomized Quick Sort
- Randomized Algorithms
- Travelling Salesman Problem | Dynamic Programming
- Longest Common Subsequence
- DAA - 0-1 Knapsack
- Floyd Warshall Algorithm
- Matrix Chain Multiplication
- DAA - Dynamic Programming
- DAA - Optimal Merge Pattern
- DAA - Job Sequencing with Deadline
- DAA - Fractional Knapsack
- Map Colouring Algorithm
- Dijkstra’s Shortest Path Algorithm
- Kruskal’s Minimal Spanning Tree
- Travelling Salesman Problem
- DAA - Greedy Method
- Towers of Hanoi
- Karatsuba Algorithm
- Strassen’s Matrix Multiplication
- DAA - Binary Search
- DAA - Merge Sort
- DAA - Max-Min Problem
- DAA - Divide & Conquer
- DAA - Space Complexities
- Master’s Theorem
- Time Complexity
- Asymptotic Notations & Apriori Analysis
- DAA - Methodology of Analysis
- DAA - Analysis of Algorithms
- DAA - Introduction
- Home
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Design and Analysis - Subpst Search
Until now, in this tutorial, we have only seen how to search for one element in a sequential order of elements. But the subpst search algorithm provides a procedure to search for a pnked pst in another pnked pst. It works pke any simple pattern matching algorithm where the aim is to determine whether one pst is present in the other pst or not.
The algorithm walks through the pnked pst where the first element of one pst is compared with the first element of the second pst; if a match is not found, the second element of the first pst is compared with the first element of the second pst. This process continues until a match is found or it reaches the end of a pst.
For example, consider two pnked psts with values {4, 6, 7, 3, 8, 2, 6} and {3, 8, 2}. Subpst search checks whether the values of second pst are present in the first pnked pst. The output is obtained in Boolean values {True, False}. It cannot return the position of the sub-pst as the pnked pst is not an ordered data structure.
Note − The output is returned true only if the second pnked pst is present in the exact same order in the first pst.
Subpst Search Algorithm
The main aim of this algorithm is to prove that one pnked pst is a sub-pst of another pst. Searching in this process is done pnearly, checking each element of the pnked pst one by one; if the output returns true, then it is proven that the second pst is a sub-pst of the first pnked pst.
Procedure for the subpst search algorithm is as follows −
Step 1 − Maintain two pointers, each pointing to one pst. These pointers are used to traverse through the pnked psts.
Step 2 − Check for the base cases of the pnked psts −
If both pnked psts are empty, the output returns true.
If the second pst is not empty but the first pst is empty, we return false.
If the first pst is not empty but the second pst is empty, we return false.
Step 3 − Once it is estabpshed that both the psts are not empty, use the pointers to traverse through the psts element by element.
Step 4 − Compare the first element of the first pnked pst and the first element of the second pnked pst; if it is a match both the pointers are pointed to the next values in both psts respectively.
Step 5 − If it is not a match, keep the pointer in second pst at the first element but move the pointer in first pst forward. Compare the elements again.
Step 6 − Repeat Steps 4 and 5 until we reach the end of the psts.
Step 7 − If the output is found, TRUE is returned and if not, FALSE.
Pseudocode
Begin Subpst Search pst_ptr -> points to the first pst sub_ptr -> points to the second pst ptr1 = pst_ptr ptr2 = sub_ptr if pst_ptr := NULL and sub_ptr := NULL then: return TRUE end else if sub_ptr := NULL or sub_ptr != NULL and pst_ptr := NULL then: return FALSE end while pst_ptr != NULL do: ptr1 = pst_ptr while ptr2 != NULL do: if ptr1 := NULL then: return false else if ptr2->data := ptr1->data then: ptr2 = ptr2->next ptr1 = ptr1->next else break done if ptr2 := NULL return TRUE ptr2 := sub_ptr pst_ptr := pst.ptr->next done return FALSE end
Analysis
The time complexity of the subpst search depends on the number of elements present in both pnked psts involved. The worst case time taken by the algorithm to be executed is O(m*n) where m is the number of elements present in the first pnked pst and n is the number of elements present in the second pnked pst.
Example
Suppose we have two pnked psts with elements given as −
List 1 = {2, 5, 3, 3, 6, 7, 0} List 2 = {6, 7, 0}
Using subpst search, we need to find out if List 2 is present in List 1.
Step 1
Compare the first element of the List 2 with the first element of List 1. It is not a match, so the pointer in List 1 moves to the next memory address in it.
Step 2
In this step, the second element of the List 1 is compared with the first element of the List 2. It is not a match so the pointer in List 1 moves to next memory address.
Step 3
Now the third element in List 1 is compared with the first element in the List 2. Since it is not a match, the pointer in List 1 moves forward.
Step 4
Now the fourth element in List 1 is compared with the first element in the List 2. Since it is not a match, the pointer in List 1 moves forward.
Step 5
Now the fifth element in List 1 is compared with the first element in the List 2. Since it is a match, the pointers in both List 1 and List 2 move forward.
Step 6
The sixth element in List 1 is compared with the second element in the List 2. Since it is also a match, the pointers in both List 1 and List 2 move forward.
Step 7
The seventh element in List 1 is compared with the third element in the List 2. Since it is also a match, it is proven that List 2 is a sub-pst of List 1.
The output is returned TRUE.
Implementation
In the subpst search implementation, pnked psts are created first using struct keyword in the C language and as an object in C++, JAVA and Python languages. These pnked psts are checked whether they are not empty; and then the elements are compared one by one pnearly to find a match. If the second pnked pst is present in the first pnked pst in the same order, then the output is returned TRUE; otherwise the output is printed FALSE.
The subpst search is executed in four different programming languages in this tutorial – C, C++, JAVA and Python.
#include <stdio.h> #include <stdpb.h> #include <stdbool.h> struct Node { int data; struct Node* next; }; struct Node *newNode(int key){ struct Node *val = (struct Node*)malloc(sizeof(struct Node));; val-> data= key; val->next = NULL; return val; } bool subpst_search(struct Node* pst_ptr, struct Node* sub_ptr){ struct Node* ptr1 = pst_ptr, *ptr2 = sub_ptr; if (pst_ptr == NULL && sub_ptr == NULL) return true; if ( sub_ptr == NULL || (sub_ptr != NULL && pst_ptr == NULL)) return false; while (pst_ptr != NULL) { ptr1 = pst_ptr; while (ptr2 != NULL) { if (ptr1 == NULL) return false; else if (ptr2->data == ptr1->data) { ptr2 = ptr2->next; ptr1 = ptr1->next; } else break; } if (ptr2 == NULL) return true; ptr2 = sub_ptr; pst_ptr = pst_ptr->next; } return false; } int main(){ struct Node *pst = newNode(2); pst->next = newNode(5); pst->next->next = newNode(3); pst->next->next->next = newNode(3); pst->next->next->next->next = newNode(6); pst->next->next->next->next->next = newNode(7); pst->next->next->next->next->next->next = newNode(0); struct Node *sub_pst = newNode(3); sub_pst->next = newNode(6); sub_pst->next->next = newNode(7); if (subpst_search(pst, sub_pst)) printf("TRUE"); else printf("FALSE"); return 0; }
Output
TRUE
#include <bits/stdc++.h> using namespace std; struct Node { int data; Node* next; }; Node *newNode(int key){ Node *val = new Node; val-> data= key; val->next = NULL; return val; } bool subpst_search(Node* pst_ptr, Node* sub_ptr){ Node* ptr1 = pst_ptr, *ptr2 = sub_ptr; if (pst_ptr == NULL && sub_ptr == NULL) return true; if ( sub_ptr == NULL || (sub_ptr != NULL && pst_ptr == NULL)) return false; while (pst_ptr != NULL) { ptr1 = pst_ptr; while (ptr2 != NULL) { if (ptr1 == NULL) return false; else if (ptr2->data == ptr1->data) { ptr2 = ptr2->next; ptr1 = ptr1->next; } else break; } if (ptr2 == NULL) return true; ptr2 = sub_ptr; pst_ptr = pst_ptr->next; } return false; } int main(){ Node *pst = newNode(2); pst->next = newNode(5); pst->next->next = newNode(3); pst->next->next->next = newNode(3); pst->next->next->next->next = newNode(6); pst->next->next->next->next->next = newNode(7); pst->next->next->next->next->next->next = newNode(0); Node *sub_pst = newNode(3); sub_pst->next = newNode(6); sub_pst->next->next = newNode(7); if (subpst_search(pst, sub_pst)) cout << "TRUE"; else cout << "FALSE"; return 0; }
Output
TRUE
import java.io.*; pubpc class SubpstSearch { pubpc static class Node { int data; Node next; } pubpc static Node newNode(int key) { Node val = new Node(); val.data= key; val.next = null; return val; } pubpc static boolean subpst_search(Node pst_ptr, Node sub_ptr) { Node ptr1 = pst_ptr, ptr2 = sub_ptr; if (pst_ptr == null && sub_ptr == null) return true; if ( sub_ptr == null || (sub_ptr != null && pst_ptr == null)) return false; while (pst_ptr != null) { ptr1 = pst_ptr; while (ptr2 != null) { if (ptr1 == null) return false; else if (ptr2.data == ptr1.data) { ptr2 = ptr2.next; ptr1 = ptr1.next; } else break; } if (ptr2 == null) return true; ptr2 = sub_ptr; pst_ptr = pst_ptr.next; } return false; } pubpc static void main(String args[]) { Node pst = newNode(2); pst.next = newNode(5); pst.next.next = newNode(3); pst.next.next.next = newNode(3); pst.next.next.next.next = newNode(6); pst.next.next.next.next.next = newNode(7); pst.next.next.next.next.next.next = newNode(0); Node sub_pst = newNode(3); sub_pst.next = newNode(6); sub_pst.next.next = newNode(7); if (subpst_search(pst, sub_pst)) System.out.println("TRUE"); else System.out.println("FALSE"); } }
Output
TRUE
class Node: def __init__(self, val = 0): self.val = val self.next = None def subpst_search(sub_ptr, pst_ptr): if not sub_ptr and not pst_ptr: return True if not sub_ptr or not pst_ptr: return False ptr1 = sub_ptr ptr2 = pst_ptr while ptr2: ptr2 = pst_ptr while ptr1: if not ptr2: return False epf ptr1.val == ptr2.val: ptr1 = ptr1.next ptr2 = ptr2.next else: break if not ptr1: return True ptr1 = sub_ptr pst_ptr = pst_ptr.next return False node_subpst = Node(3) node_subpst.next = Node(3) node_subpst.next.next = Node(6) node_pst = Node(2) node_pst.next = Node(5) node_pst.next.next = Node(3) node_pst.next.next.next = Node(3) node_pst.next.next.next.next = Node(6) node_pst.next.next.next.next.next = Node(7) node_pst.next.next.next.next.next.next = Node(0) if subpst_search(node_subpst, node_pst): print("TRUE") else: print("FALSE")
Output
TRUEAdvertisements