Professional Documents
Culture Documents
KP - Report 3 PDF
KP - Report 3 PDF
KP - Report 3 PDF
Training
Report on
DSA in C++
from
GeeksForGeeks
Disha Singh
2000270210029
i
ABSTRACT
Disha Singh
CONTENT
1) ESSENTIAL C AND C++ CONCEPTS
1. ARRAY BASICS
2. STRUCTURES
3. POINTERS
4. REFERENCE IN C++
5. POINTER TO STRUCTURE
6. FUNCTION
7. PARAMETER PASSING METHODS
8. ARRAY AS PARAMETER
9. STRUCTURE AS PARAMETER
10.CONSTRUCTOR
11. TEMPLATE
2) RECURSION
1.HOW RECURSION WORKS
2.GENERALISING RECURSION
3.HOW RECURSION USES STACK RECURRENCE
RELATION-TIME COMPLEXITY OF RECURSION
4.STATIC AND GLOBAL VARIABLES
5.TAIL RECURSION
6.HEAD RECURSION
7.TREE RECURSION
8.INDIRECT RECURSION
9.NESTED RECURSION
10.PROGRAMS OF RECURSION
3) ARRAY REPRESENTATION
1.INTRODUCTION TO ARRAY S
2. ARRAYS VS DYNAMIC ARRAYS
3.2D-ARRAY
4) ARRAY ADT
1.ARRAY ADT
2.INSERTING IN ARRAY
3.DELETING FROM ARRAY
4.LINERA SEARCH
5.INPROVING LINEAR SEARCH
6.BINARY SEARCH
7.BINARY SEARCH ALGORITHIM
8.ANALYSIS OF BINARY SEARCH
9.GET ()/SET ()/AVG () FUNCTIONS ON ARRAY
10.REVERSE AND SHIFT AN ARRAY
11.CHECK IF ARRAY IS SORTED
12.MERGING ARRAYS SET OPERATOR ON ARRAY -: UNION,
INTERSECTION, DIFFERNCE
5) STRINGS
1.INTRODUCTION TO STRINGS
2.FINDING LENGTH OF A STRING
3.CHANGING CASE OF A STRING
4.COUNTING WORDS AND VOWELS ON A STRING
5.VALIDATING A STRING
6.REVERSING A STRING
7.COMPARING STRINGS CHECKING PLAINDROME
8.FINDING DUPLICATES IN A STRING FINDING FUPLICATES IN A
SGTRING USING BITWISE OPERATIONS
9.CHECKING IF 2 STRINGS ARE ANAGRAM
6) MATRICES
1.INTRODUCTION
2.DIAGONAL MATRIX
3.C++ CLASS FOR DIAGONAL MATRIX
4.LOWER TRIANGULAR MATRIX ROW-MAJOR MAPPING
5.UPPER TRIANGULAR MATRIX ROW-MAJOR MAPPING
6.UPPER TRIANGULAR MATRIX COLIMN-MAJOR MAPPING
7.SYMMETRIC MATRIX
8.TRI-DIGONAL AND TRI-BAND MATRIX
7)LINKED LIST
1.WHY WE NEED DYNAMIC DATASTRUCTURES
2.ABOUT LINKED LIST
3.DISPLAY LINKED LIST
4.RECURSIVE DISPLAY FOR LINKED LIST
5.COUNTING NODES IN LINKED LIST
6.SUM OF ALL ELEMENTS IN A LINKED LIST
7.SEARCHING IN A LINKED LIST
8.INSERTING IN A LINKED LIST
9.CREATING A LINKED LIST USING INSERT
10.CREATING A LINKED LIST BY INSERTING AT LAST
11.INSERTING IN A SORTED LINKED LIST
12.DELETING FROM A LINKED LIST
13.CHECK IF A LINKED LIST IS SORTED
14.REMOVE DUPLICATES FROM A SORTED LINKED LIST
15.REVERSING A LINKED LIST
16.REVERSING USING SLIDING POINTERS
17.CONCATENATING 2 LINKED LIST
18.MERGING 2 LINKED LISTS
19.CHECK FOR LOOP IN LINKED LIST
20.CIRCULAR LINKED LIST
21.DISPLAY CIRCULAR LINKED LIST
22.INSERTING IN A CIRCULAR LINKED LIST
23.DELETING FROM A CIRCULAR LINKED LIST
24.DOUBLY LINKED LIST
25.INSERTING IN A BOUBLY LINKED LIST
26.FELETING FROM A DOUBLY LINKED LIST
27.REVERSE A DOUBLY LINKED LIST
28.CIRCULAR DOUBLY LINKED LIST
29.COMPARISON OF ARRAY WITH LINKED LIST
8 STACK
INTRODUCTION TO STACK
1.STACK USING ARRAY
2.IMPLEMENTATION OF STACK USING ARRAY
3.STACK USING LINKED LIST
INTRODUCTION
The most important point that you need to remember is for implementing the logical
data structures (Stack, Queue, Trees, Graphs, Hash Tables) we either use an array
or linked list or a combination of array and linked list physical data structures. So,
that is all we have given the introduction of various types of data structures. This
was just the introduction to give us awareness.
c) ADT (ABSTRACT DATA TYPE)
Stack −
Queue
Space Complexity
Space complexity of an algorithm represents the amount of memory space needed
the algorithm in its life cycle.
Space needed by an algorithm is equal to the sum of the following two components
A fixed part that is a space required to store certain data and variables (i.e. simple
variables and constants, program size etc.), that are not dependent of the size of the
problem.
A variable part is a space required by variables, whose size is totally dependent on
the size of the problem. For example, recursion stack space, dynamic memory
allocation etc.
Space complexity S(p) of any algorithm p is S(p) = A + Sp(I) Where A is treated as the
fixed part and S(I) is treated as the variable part of the algorithm which depends on
instance characteristic I. Following is a simple example that tries to explain the
concept
Time Complexity
Time Complexity of an algorithm is the representation of the amount of time required
by the algorithm to execute to completion. Time requirements can be denoted or
defined as a numerical function t(N), where t(N) can be measured as the number of
steps, provided each step takes constant time.
For example, in case of addition of two n-bit integers, N steps are taken.
Consequently, the total computational time is t(N) = c*n, where c is the time
consumed for addition of two bits. Here, we observe that t(N) grows linearly as
input size increases.
RECURSION
a) HOW RECURSION
WORKS:
When any function is called from main(), the memory is allocated to it on
the stack. A recursive function calls itself, the memory for a called
function is allocated on top of memory allocated to the calling function
and a different copy of local variables is created for each function call.
When the base case is reached, the function returns its value to the
function by whom it is called and memory is de-allocated and the process
continues.
b) TAIL
RECURSION:
Tail recursion is defined as a recursive function in which the recursive call
is the last statement that is executed by the function. So basically nothing
is left to execute after the recursion call.
void print(int n)
{
if (n < 0)
return;
cout << " " << n;
c) HEAD RECURSION:
If a recursive function calling itself and that recursive call is the first statement in
the function then it9s known as Head Recursion. There no statement, no
operation before the call. The function doesn9t have to process or perform any
operation at the time of calling and all operations are done at returning time.
Example:
<bits/stdc++.h>
using namespace std;
// Recursive function
void fun(int n)
{
if (n > 0) {
// First statement in the function
fun(n - 1);
cout << " "<< n;
}
}
// Driver code
int main()
{
int x = 3;
fun(x);
return 0;
}
d) TREE RECURSION:
Dynamic arrays differ from static arrays in that they don’t have a
fixed size. However, this is at the cost of having quick appends. How
a dynamic array works is that it resizes itself whenever it runs out of
space. This is usually by doubling itself. For example, if its size
defaulted to 10 indices then it would double to 20. Let’s take a closer
look at how it does this:
Static Arrays:
When you allocate an array in a low-level language like C++ or Java, you
have to specify upfront how many indices you want your array to have like
so:
This makes the array static because it only has five indices that you
can use. This makes it impossible to append items when all five
indices are filled with values. The upside to this is that if you know
that you are only going to have five elements, then appending to this
array becomes worst case O(1) time.
c) 2D ARRAYS:
If you want to change the size, you need to create a new array of the desired
size, and then copy elements from the old array to the
new array, and use the new array. In our example, arr can only hold int
values. Arrays can hold primitive values, unlike ArrayList, which can only
hold object values.
ARRAY ADT: a)
ADT indicates for Abstract Data Type.
Arrays are defined as ADT’s because they are capable of holding
contiguous
elements in the same order. And they permit
access for the specific element via index or position.
They are abstract because they can be String, int or Person
Advantages
Fast, random access of items or elements.
Very memory efficient, very little memory is needed other than
that needed to store the contents.
Disadvantages
Slow insertion and deletion of elements
Array size must be known when the array is created and is fixed (static)
b) Insertion in array:
Given an array arr of size n, this article tells how to
insert an element x in this array arr at a specific position
pos.
#include <stdio.h>
int main()
{
int arr[100] = { 0 };
int i, x, po
s, n = 10;
// initial array of size 10
for (i = 0; i < 10; i++)
arr[i] = i + 1;
// print the original array
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
// element to be inserted
x = 50;
// insert x at pos
arr[pos - 1] = x;
// print the updated array
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
return 0;
#include<bits/stdc++.h>
using namespace std;
d) LINEAR SEARCH:
Follow the given steps to solve the problem: Start from the leftmost
element of arr[] and one by one compare x
with each element of arr[]
If x matches with an element, return the index.
If x doesn9t match with any of the elements, return -1.
#include <stdio.h>
// Driver's code
int main(void)
{
int arr[] = { 2, 3, 4, 10, 40 };
int x = 10;
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
int result = search(arr, N, x);
(result == -1)
? printf("Element is not present in array")
: printf("Element is present at index %d", result);
return 0;
}
e) BINARY SEARCH:
Binary Search Algorithm: The basic steps to perform Binary Search are:
1.Begin with the mid element of the whole array as a search key.
2.If the value of the search key is equal to the item then return an
3.index of the search key.
4.Or if the value of the search key is less than the item in the middle
5.of the interval, narrow the interval to the lower half.
6.Otherwise, narrow it to the upper half.
7.Repeatedly check from the second point until the value is found or
8.the interval is empty.
1) ITERATIVE METHOD:
return mid
high = mid – 1
2) RECURSIVE METHOD:
binarySearch(arr, x, low, high)
if low > high
return False
else
mid = (low + high) / 2
if x == arr[mid]
return mid
else if x > arr[mid]
// x is on the right
STRING:
a) INTRODUCTION TO STRINGS:
// Driver Code
int main()
{
string str = "ABC";
int n = str.size();
permute(str, 0, n-1);
return 0;
MATRICES:
a) INTRODUCTION:
What is Matíix in Data Stíuctuíe?
b) DIAGONAL MATRIX:
#include <bits/stdc++.h>
using namespace std;
C) SYMMETRIC MATRIX:
#include <iostream>
using namespace std;
// Driver code
int main()
{
int mat[][MAX] = { { 1, 3, 5 },
{ 3, 2, 4 },
{ 5, 4, 1 } };
if (isSymmetric(mat, 3))
cout << "Yes";
else
cout << "No";
return 0;
}
. Define a node current which initially points to the head of the list.
a. Traverse through the list till current points to null.
b. Display each node by making current to point to node next to it in each
iteration.
#include <stdio.h>
#include <stdlib.h>
1. //Represent a node of singly linked list
2. struct node{
3. int data;
4. struct node *next;
5. };
6.
7. //Represent the head and tail of the singly linked list
8. struct node *head, *tail = NULL;
9.
10. //addNode() will add a new node to the list
11. void addNode(int data) {
12. //Create a new node
13. struct node *newNode = (struct node*)malloc(sizeof(struct node));
14. newNode->data = data;
15. newNode->next = NULL;
16.
17. //Checks if the list is empty
18. if(head == NULL) {
19. //If list is empty, both head and tail will point to new node
20. head = newNode;
21. tail = newNode;
22. }
23. else {
24. //newNode will be added after tail such that tail's next will point
to newN ode
25. tail->next = newNode;
26. //newNode will become new tail of the list
27. tail = newNode;
28. }
29. }
30.
31. //display() will display all the nodes present in
the list 32. void display() {
33. //Node current will point to head
34. struct node *current = head;
35.
36. if(head == NULL) {
37. printf("List is empty\n");
38. return;
39. }
40. printf("Nodes of singly linked list: \n");
41. while(current != NULL) {
42. //Prints each node by incrementing pointer
43. printf("%d ", current->data);
44. current = current->next;
45. }
46. printf("\n");
47. }
48.
49. int main()
50. {
51. //Add nodes to the list
52. addNode(1);
53. addNode(2);
54. addNode(3);
55. addNode(4);
56.
57. //Displays the nodes present in the list
58. display();
Push:
Adds an item to the stack. If the stack is full, then it is said to be an Overflow
condition.
Algorithm for push:
begin
if stack is full
return
endif
else
increment top
stack[top] assign value
end else
end procedure
Pop:
Removes an item from the stack. The items are popped in the reversed order
in which they are pushed. If the stack is empty, then it is said to be an
Underflow condition.
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.
Algorithm for Top:
begin
return stack[top]
end procedure
isEmpty:
Returns true if the stack is empty, else
false. Algorithm for isEmpty:
begin
if top < 1
return true
else
return false
end procedure
Understanding stack practically:
There are many real-life examples of a stack. Consider the simple example of
plates stacked over one another in a canteen. The plate which is at the top is
the first one to be removed, i.e. the plate which has been placed at the
bottommost position remains in the stack for the longest period of time. So, it
can be simply seen to follow the LIFO/FILO order.
Time Complexity
Operations Complexity
push() O(1)
pop() O(1)
isEmpty() O(1)
size() O(1)
Types of Stacks:
4. Simple Graph:
A simple graph is a graph that does not contain more than one edge
between the pair of vertices. A simple railway track connecting different
cities is an example of a simple graph.
5. Multi Graph:
Any graph which contains some parallel edges but
doesn’t contain any self-loop is called a multigraph. For example a Road Map. Parallel Edges:
If two vertices are connected with more than one
edge then such edges are called parallel edges that are many routes
7. Complete Graph:
A simple graph with n vertices is called a complete graph if the degree of each
vertex is n-1, that is, one vertex is attached with n-1 edges or the rest of the
vertices in the graph. A complete graph is also called Full Graph.
8. Pseudo Graph:
A graph G with a self-loop and some multiple edges is called a pseudo graph.
9. Regular Graph:
A simple graph is said to be regular if all vertices of graph G are of equal degree.
All complete graphs are regular but vice versa is not possible.
10.
A Bipartite
graph G = (V,Graph:
E) is said to be a bipartite graph if its vertex set V(G) can be
partitioned into two non-empty disjoint subsets. V1(G) and V2(G) in such a way
that each edge e of E(G) has one end in V1(G) and another end in V2(G). The
partition V1 U V2 = V is called Bipartite of G. Here in the figure: V1(G)={V5, V4,
V3} and V2(G)={V1, V2}
11. Labeled Graph:
If the vertices and edges of a graph are labeled with name, date, or weight
then it is called a labeled graph. It is also called Weighted Graph.
OMEGA NOTATION :
The notation
Ω(n) is the formal way to express the lower bound of an algorithm's running time. It measures the
bes cas an algorithm can possibly take to complete.
Theta Notationθ,
The notation
θ(n) is the formal way to express both the lower bound and the upper bound of an algorithm's running tim
CONCLUSION
In conclusion, data structures are a great tool to computer science and
the professionals who utilize them. Data structures have their advantages
and disadvantages like everything in our lives. Only advance users can
make changes to data structures, and any problem involving data
structure will need a professional to rectify. Luckily, there are more
advantages than there are disadvantages. Data structures allow
information storage, it provides the means for management of large data
like databases, work together and are necessary for efficient algorithms,
safe storage of data, allows easier processing of data, and the use of the
internet to access data anytime. With those odds, this makes it easy to
accept that without these applications in our lives, life would be that much
harder when dealing with computer science and even our day to day tasks
REFERENCES
www..https.leetcode.com
www.https://geeks for geeks com
www.cpalgorithum.com
www.codzilla.com
www.freecodecamp.org
THANK YOU