You are on page 1of 54

Design Analysis of algorithm Experiment (CSPC-226)

Academic Year:2020-2021

SUBMITTED BY: SUBMITTED TO:


Arpitveer singh Dr Urvashi Bansal
19103021 Assistant Professor
CSE/4 th SEMESTER CSE Department
Group : G1

COMPUTER SCIENCE AND ENGINEERING DEPARTMENT


DR. B.R. AMBEDKAR NATIONAL INSTITUTE OF TECHNOLOGY
JALANDHAR
INDEX

SR.NO. PROGRAM DATE

1. WAP to implement the heaps along with various operations based 07-02-2021
on them such as insertion,deletion, extracting minimum/
maximum element, heap sort, priority queues.

2. WAP to implement the Counting sort, Radix Sort and Bucket sort 21-02-2021
linear time algorithm, and also analyse the time complexity of
algorithms.

3. WAP to implement the greedy algorithms like kruskal & prims to 28-02-2021
find the minimum spanning tree from a given set of nodes and
edges, also discuss the time complexity of algorithms.
4. WAP to implement the various graph based algorithms Dijkstra’s 07-03-2021
& bellman ford shortest path algorithm, and analyse the time
complexity of algorithm.
5. WAP to implement the breadth & depth first search and fractional 14-03-2021
knapsack algorithm, also discuss the time complexity of
algorithm.
6. WAP to implement an activity-selection problem and job 09-03-2021
sequencing with
deadline.
7. WAP to implement Huffman codes with the help of example, also 15-03-2021
discuss the
time complexity of algorithms.
8. WAP to implement the Matrix chain multiplication and assembly 22-03-2021
line scheduling algorithm and analyse the time complexity of
algorithm.
9. WAP to implement the Longest common subsequence and 0/1 29-03-2021
Knapsack algorithm and analyse the time complexity of
algorithm.
10. WAP to implement the Optimal binary search trees and all pair 06-04-2021
shortest path algorithm(Floyd-Warshall algorithm) and analyse
the time complexity of algorithm.
11 Given an array, find a Subarray with consecutive elements and 20-4-2021
maximum sum. Negative numbers allowed.
Experiment-1
Aim:- Write a program to implement the heaps along with various operations based on them such as
insertion, deletion, extracting minimum/ maximum element, heap sort, priority queues.

THEORY:
1. A Heap is a type of complete binary tree following a particular condition that is the value of all
parent nodes is either maximum than all its child nodes, forming a max heap or minimum than
both its child nodes, forming a min heap.
2. A heap can be implemented by using an array such that for ith index its child nodes will be at 2i
and 2i+1 th location. Also, for a node at ith index, its parent node’s location can be calculated as
i/2.(for index starting from 1).
3. Insertion : Suppose we need to insert an element in max heap,then we add it as a leaf node and
then compare its values with parent nodes and swap if the parent value is less;
4. Deletion: To delete an element we swap the last leaf node with the root node and return value of
root node and the perform heapification to balance our tree(min or max).
5. Heap sort : This takes nlogn time for building heap tree and nlogn for deletion .

INSERTION AND DELETION:

#include<bits/stdc++.h>
#include<cmath>
using namespace std;
class tree
{
    vector<int>a;
    static int k;
public:
    tree()
    {
        a.push_back(0);
    }

    void insertt()
    {
        int n;
        cout<<"enter the number to be inserted:";
        cin>>n;
        if(k<a.size())
            a[k]=n;
        else
            a.push_back(n);
        int v=k;
        while(v/2)
        {
            if(a[v]>a[v/2])
            {
                swap(a[v],a[v/2]);
                v=v/2;
            }
            else
                break;
        }
        k++;
    }

    void show()
    {
        for(int i=1;i<k;i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }

    void deletee(){
        if(k==1)
        {
            cout<<"the list is empty\n";
            return;
        }

        int num=a[1];
        k--;
        a[1]=a[k];
        int i=1;
        while(2*i<=k)
{
            if(a[i]<a[2*i])
{
                if((2*i+1<k)&&(a[2*i+1]>a[2*i]))
{
                    swap(a[i],a[2*i+1]);
                    i=2*i+1;
                }
                else{
                    swap(a[i],a[2*i]);
                    i=2*i;
                }
            }
            else if(((2*i+1)<k)&&(a[2*i+1]>a[i]))
            {
                swap(a[i],a[2*i+1]);
                i=2*i+1;
            }
            else
                break;
        }
        a[k]=num;
    }
};

int tree::k=1;
int main()
{
    tree t;
    cout<<"1.insert\n2.show elements\n3.delete\n";
    int n;
    while(1)
{
        cout<<"\nenter your choice:";
        cin>>n;
        switch(n)
 {
        case 1:
            t.insertt();
            break;
        case 2:
            t.show();
            break;
        case 3:
            t.deletee();
            break;
        default:
            exit(0);
}
    }
    return 0;
}

OUTPUT:
HEAP SORT:
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cout<<"number of elements : ";
    cin>>n;
    int a[n+1];
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        int t=i;
        while(t>1)
        {
            if(a[t]>a[t/2])
                swap(a[t],a[t/2]);
            t=t/2;
        }
    }

    for(int i=1;i<=n;i++)
    {
        int index=n+1-i;
        swap(a[index],a[1]);
        int r=1;
        while(2*r<index)
        {
            if(a[r]<a[2*r])
            {
                if(2*r+1<index&&a[2*r+1]>a[2*r])
                    swap(a[r],a[2*r+1]);
                else
                    swap(a[r],a[2*r]);
            }
            else if(2*r+1<index&&a[2*r+1]>a[r])
                swap(a[r],a[2*r+1]);
            else
                break;
            r=2*r;
        }
    }
    cout<<"sorted array : ";
    for(int i=1;i<=n;i++)
        cout<<a[i]<<" ";
}

OUTPUT:

TIME COMPLEXITY:

For insertion of n elements : n log n

For deletion of n elements : n log n

For heap sort : O(nlogn + nlogn)

=>O(nlogn)

EXTRACT MAXIMUM AND MINIMUM, PRIORITY QUEUE:


#include<bits/stdc++.h>
#include<cmath>
using namespace std;
class tree{
    vector<int>a;
    static int k;
public:
    tree() {
        a.push_back(0);
    }
    void level_up() {
        int v=k;
        while(v/2){
            if(a[v]>a[v/2]) {
                swap(a[v],a[v/2]);
                v=v/2;
            }
            else
                break;
        }
    }
    void insertt()
    {
        int n;
        cout<<"enter the number to be inserted:";
        cin>>n;
        if(k<a.size())
            a[k]=n;
        else
            a.push_back(n);
        level_up();
        k++;
    }
    void show()
    {
        for(int i=1;i<k;i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }
    int deletee()
    {
        if(k==1)
            return -1;

        int num=a[1];
        k--;
        a[1]=a[k];
        int i=1;
        while(2*i<=k)
        {
            if(a[i]<a[2*i])
            {
                if((2*i+1<k)&&(a[2*i+1]>a[2*i]))
                {
                    swap(a[i],a[2*i+1]);
                    i=2*i+1;
                }
                else
                {
                    swap(a[i],a[2*i]);
                    i=2*i;
                }
            }
            else if(((2*i+1)<k)&&(a[2*i+1]>a[i]))
            {
                swap(a[i],a[2*i+1]);
                i=2*i+1;
            }
            else
                break;
        }
        a[k]=num;
        return num;
    }
    void extract_max()
    {
        int t=deletee();
        if(t!=-1)
            cout<<"maximum element : "<<t<<endl;
        else
            cout<<"the list is empty\n";
    }
    void extract_min()
{
        int i=1;
        while(2*i<k) {
            int index=2*i;
            if(index+1<k) {
                if(a[index+1]<a[index])
                    i=index+1;
                else
                    i=index;
            }
            else
                i=index;
        }
        cout<<"minimum element : "<<a[i]<<endl;
        k--;
        swap(a[k],a[i]);
    }
};

int tree::k=1;

int main()
{
    tree t;
    cout<<"1.insert\n2.show elements\n3.extract maximum\n4.extract minimum\n";

    int n;
    while(1)
{
        cout<<"\nenter your choice:";
        cin>>n;
        switch(n)
{
        case 1:
            t.insertt();
            break;
        case 2:
            t.show();
            break;
        case 3:
            t.extract_max();
            break;
        case 4:
            t.extract_min();
            break;
        default:
            exit(0);
        }
    }
    return 0;
}

OUTPUT:
Experiment-2
Aim:- Write a program to implement the Counting sort, Radix Sort and Bucket sort linear time
algorithm, and also analyse the time complexity of algorithms.

Theory :
Counting sort : In this we make an array of n elements (highest number in the series). Then calculate
the frequency of each element . Next step is to calculate cumulative frequency and then place the
elements according to the position they should occupy in the sorted array and decrease the cumulative
frequency of corresponding element.
Radix sort: In this we sort the numbers according to their digits at one’s place, then at tenth’s place
and so on. We move from ones place to higher place values and push elements into vectors according
to the current place being evaluated and then pop all the elements starting from vector[0] to vector[9]
and this process continuous for d (maximum number of digits) iterations.
Bucket sort : Bucket Sort is a sorting technique that sorts the elements by first dividing the elements
into several groups called buckets. The elements inside each bucket are sorted using any of the
suitable sorting algorithms or recursively calling the same algorithm.

COUNTING SORT:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cout<<"enter size of array : ";
    cin>>n;
    int a[n],b[n];
    int max_ele=INT_MIN;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        max_ele=max(max_ele,a[i]);
    }
    int countt[max_ele+1]={0};
    for(int i=0;i<n;i++)
        countt[a[i]]++;
    for(int i=1;i<=max_ele;i++)
        countt[i]=countt[i]+countt[i-1];
    for(int i=0;i<n;i++){
        b[--countt[a[i]]]=a[i];
    }
    for(int i=0;i<n;i++)
        a[i]=b[i];
    cout<<"sorted array : ";
    for(int i=0;i<n;i++)
        cout<<a[i]<<" ";
}
OUTPUT:

TIME COMPLEXITY:

First the whole array is traversed to find maximium : O(n)

Hash is used and frequency of each element is stored : O(n)

Cumulative frequency is calculated : O(n)

The sorted array is stored in a second array : O(n)

the sorted values are copied into original array : O(n)

total : O(5*n) = O(n)

RADIX SORT:
#include<bits/stdc++.h>
using namespace std;
int base(int n){
    int count=0;
    while(n)
    {
        count++;
        n=n/10;
    }
    return count;
}
int main(){
    int n;
    cout<<"enter size : ";
    cin>>n;
    int arry[n];
    cout<<"elements : \n";
    int max_ele=INT_MIN;
    for(int i=0;i<n;i++)
    {
        cin>>arry[i];
        max_ele=max(max_ele,arry[i]);
    }
    int digits=base(max_ele);
    vector<int>v[10];
    for(int k=0;k<digits;k++)
    {
        int div=pow(10,k);
        for(int j=0;j<n;j++)
        {
            v[(arry[j]/div)%10].push_back(arry[j]);
        }
        int index=0;
        for(int i=0;i<10;i++)
        {
            for(int j=0;j<v[i].size();j++)
            {
                arry[index]=v[i][j];
                index++;
            }
            v[i].clear();
        }
    }
    cout<<"sorted array :\n";
    for(int i=0;i<n;i++)
        cout<<arry[i]<<" ";
    cout<<endl;
    return 0;
}
OUTPUT:

TIME COMPLEXITY:

let number of digits in largest number be d


total numbers be n
number of traversals for each digit : n
total =O(n*d)

BUCKET SORT:
#include<bits/stdc++.h>
using namespace std;
int base(int n)
{
    int count=0;
    while(n)
    {
        count++;
        n=n/10;
    }
    return count;
}
int main()
{
    int n;
    cout<<"enter size : ";
    cin>>n;
    int arry[n];
    cout<<"elements : \n";
    int max_ele=INT_MIN;
    for(int i=0;i<n;i++)
    {
        cin>>arry[i];
        max_ele=max(max_ele,arry[i]);
    }
    int digits=base(max_ele);
    vector<int>v[10];

    int div=pow(10,digits-1);
    for(int j=0;j<n;j++)
        v[arry[j]/div].push_back(arry[j]);

    int index=0;
    for(int k=0;k<10;k++)
    {
        if(v[k].size())
            sort(v[k].begin(),v[k].end());
        for(int j=0;j<v[k].size();j++)
        {
            arry[index]=v[k][j];
            index++;
        }
    }
    cout<<"sorted array :\n";
    for(int i=0;i<n;i++)
        cout<<arry[i]<<" ";
    cout<<endl;
    return 0;
}
OUTPUT:

TIME COMPLEXITY:
First we push elements into buckets(containers such as vector) according to the most significant place
value and then sort the elements in each bucket by applying any of the sorting algorithm . At last we
pop all the elements back into original array.
Experiment-3
Aim:- Write a program to implement the greedy algorithms like kruskal & prims to find the
minimum spanning tree from a given set of nodes and edges, also discuss the time complexity of
algorithms.
Theory:
Kruskal : A greedy algorithm used to find a minimum spanning tree with n vertices and n-1 edges to
minimize the cost of the tree. It sorts the edges and treat each single node as an individual tree and
then starts from any vertex and add on the vertices with lower cost.

Prim’s : Prim’s algorithm is a greedy algorithm. It is used to find a minimum spanning tree for a
weighted graph. It gives a tree of n number of vertices with n-1 edges which will be a subset of the set
of all edges in such a way that cost of the travelling from any one node to another is minimum. The
algorithm operates by building this tree one vertex at a time, from an arbitrary starting vertex, at each
step adding the cheapest possible connection from the tree to another vertex.
KRUSKAL’S :

#include<bits/stdc++.h>
using namespace std;
class graph
{
    int nodes,edges;
    vector<pair<int,pair<int,int>>>adj;
    vector<pair<int,pair<int,int>>>solution;
    int *parent;
    bool *status;
public:
    graph()
    {
        cout<<"number of nodes : ";
        cin>>nodes;
        cout<<"enter number of edges : ";
        cin>>edges;
        parent=new int[nodes];
        for(int i=0;i<nodes;i++)
            parent[i]=i;
        cout<<"enter edges :\n";
        int s,d,dis;
        for(int i=0;i<edges;i++)
        {
            cin>>s>>d>>dis;
            adj.push_back({dis,{s,d}});
        }
    }
    int check_parent(int s)
    {
        if(parent[s]==s)
            return s;
        else
            return(check_parent(parent[s]));
    }
    void kruskal()
    {
        sort(adj.begin(),adj.end());
        int sol_count=0;
        int i=0;
        while(sol_count<nodes&&i<edges)
        {
            int p1=check_parent(adj[i].second.first);
            int p2=check_parent(adj[i].second.second);
            if(p1!=p2)
            {
                solution.push_back(adj[i]);
                sol_count++;
                parent[adj[i].second.second]=p1;
            }
            i++;
        }
    }
    void show_solution()
    {
        cout<<setw(5)<<"dis"<<setw(5)<<"v1"<<setw(5)<<"v2"<<endl;
        int cost=0;
        for(int i=0;i<solution.size();i++)
        {
            cout<<setw(5)<<solution[i].first<<setw(5)<<solution[i].second.first<<setw(5)<<solution[i].se
cond.second<<endl;
            cost+=solution[i].first;
        }
        cout<<"\nthe cost of minimum spanning tree is : "<<cost<<endl;
    }
};
int main()
{
    graph g;
    g.kruskal();
    g.show_solution();
    return 0;
}

OUTPUT:
TIME COMPLEXITY:
 For sorting : O(ElogE)

For traversing the edges after sorting :O(E)


For checking parent : O(ElogV)

So total time complexity : O(ElogE + E + ElogV)


  =>O(ElogE)

PRIMS:
#include<bits/stdc++.h>
using namespace std;
class graph
{
int nodes,edges;
vector<pair<int,pair<int,int>>>adj;
vector<pair<int,pair<int,int>>>solution;
int *parent;
bool *status;
public:
graph()
{
cout<<"number of nodes : ";
cin>>nodes;
cout<<"enter number of edges : ";
cin>>edges;
parent=new int[nodes];
for(int i=0;i<nodes;i++)
parent[i]=i;
cout<<"enter edges :\n";
int s,d,dis;
for(int i=0;i<edges;i++)
{
cin>>s>>d>>dis;
adj.push_back({dis,{s,d}});
}
}
int check_parent(int s)
{
if(parent[s]==s)
return s;
else
return(check_parent(parent[s]));
}
void kruskal()
{
sort(adj.begin(),adj.end());
int sol_count=0;
int i=0;
while(sol_count<nodes-1&&i<edges)
{
int p1=check_parent(adj[i].second.first);
int p2=check_parent(adj[i].second.second);
if(p1!=p2)
{
solution.push_back(adj[i]);
sol_count++;
parent[adj[i].second.second]=p1;
}
i++;
}
}
void show_solution()
{
cout<<setw(5)<<"dis"<<setw(5)<<"v1"<<setw(5)<<"v2"<<endl;
int cost=0;
for(int i=0;i<solution.size();i++)
{
cout<<setw(5)<<solution[i].first<<setw(5)<<solution[i].second.first<<setw(5)<<solution[i].second.se
cond<<endl;
cost+=solution[i].first;
}
cout<<"\nthe cost of minimum spanning tree is : "<<cost<<endl;
}
};
int main()
{
graph g;
g.kruskal();
g.show_solution();
return 0;
}
OUTPUT:

TIME COMPLEXITY:
To search for V-1 edges where v=no. Of vertices ,we need to run a loop V times and in each loop we
need to find the minimum weight of an edge whose one vertex is visited and one unvisited and again a
second loop is needed to update the weights.
So time complexity : O ( V*(V+V))
=>O ( V*2*V) =>O(2*V*V) =>O(V*V)
Experiment-4
Aim:- WAP to implement the various graph based algorithms Dijkstra’s & bellman ford shortest path
algorithm, and analyse the time complexity of algorithm.
THEORY:

Dijkstra's algorithm :
Dijkstra's algorithm allows us to find the shortest path between any two vertices of a graph. We need
to maintain the path distance of every vertex. We can store that in an array of size v, where v is the
number of vertices. We also want to be able to get the shortest path, not only know the length of the
shortest path. For this, we map each vertex to the vertex that last updated its path length. Once the
algorithm is over, we can backtrack from the destination vertex to the source vertex to find the path.
Bellman Ford:
It algorithm helps us find the shortest path from a vertex to all other vertices of a weighted graph. It is
similar to Dijkstra's algorithm but it can work with graphs in which edges can have negative weights.
We need to maintain the path distance of every vertex. We can store that in an array of size v, where v
is the number of vertices. We also want to be able to get the shortest path, not only know the length of
the shortest path. For this, we map each vertex to the vertex that last updated its path length. Once the
algorithm is over, we can backtrack from the destination vertex to the source vertex to find the path

BELLMAN FORD:
#include<bits/stdc++.h>
using namespace std;
class graph
{
    vector<vector<int>>adj;
    int nodes,edges;
    bool *status;
    int *dis;
public:
    graph()
    {
        cout<<"nodes : ";
        cin>>nodes;
        cout<<"edges : ";
        cin>>edges;

        for(int i=0;i<nodes;i++)
            adj.push_back(vector<int>(nodes,INT_MAX));

        dis=new int[nodes];
        cout<<"enter edges : \n";

        for(int i=0;i<edges;i++)
        {
            int s,d,dis;
            cin>>s>>d>>dis;
            adj[s][d]=dis;
        }

        status=new bool[nodes];
        memset(status,false,nodes);
    }

    void show()
    {
        for(int i=0;i<nodes;i++)
        {
            for(int j=0;j<nodes;j++)
            {
                if(adj[i][j]!=INT_MAX)
                    cout<<setw(5)<<adj[i][j];
                else
                   cout<<setw(5)<<"inf";
            }
            cout<<endl;
        }
    }

    void bellman()
    {
        for(int i=0;i<nodes;i++)
            dis[i]=INT_MAX;

        cout<<endl;
        dis[0]=0;
        for(int k=1;k<nodes;k++)
        {
            for(int i=0;i<nodes;i++)
            {
                for(int j=0;j<nodes;j++)
                {
                    if(adj[i][j]!=INT_MAX&&dis[i]!=INT_MAX&&dis[j]>dis[i]+adj[i][j])
                        dis[j]=dis[i]+adj[i][j];
                }
            }
        }
    }

    void show_ans()
    {
        cout<<"solution : \n";
        cout<<setw(5)<<"node"<<setw(5)<<"dis"<<endl;

        for(int i=0;i<nodes;i++)
        {
            cout<<setw(5)<<i;
            if(dis[i]!=INT_MAX)
            cout<<setw(5)<<dis[i]<<endl;
            else
                cout<<setw(5)<<"inf"<<endl;
        }
    }

};
int main()
{
    graph g;
    g.bellman();
    g.show_ans();
    return 0;
}

OUTPUT:

TIME COMPLEXITY:
We have to traverse all the edges (N-1) times where n is the number of nodes so the time complexity
is O(N*E).
In worst case number of edges can be N*N
So worst case time complexity is O(N^3)

DIJKSTRA:

#include<bits/stdc++.h>
using namespace std;
class graph
{
    vector<vector<int>>adj;
    int nodes,edges;
    bool *status;
    int *dis;
public:
    graph()
    {
        cout<<"nodes : ";
        cin>>nodes;
        cout<<"edges : ";
        cin>>edges;
        for(int i=0;i<nodes;i++)
            adj.push_back(vector<int>(nodes,INT_MAX));
        dis=new int[nodes];
        cout<<"enter edges : \n";
        for(int i=0;i<edges;i++)
        {
            int s,d,dis;
            cin>>s>>d>>dis;
            adj[s][d]=dis;
        }
        status=new bool[nodes];
        memset(status,false,nodes);
    }
    void show()
    {
        for(int i=0;i<nodes;i++)
        {
            for(int j=0;j<nodes;j++)
            {
                if(adj[i][j]!=INT_MAX)
                    cout<<setw(5)<<adj[i][j];
                else
                   cout<<setw(5)<<"inf";
            }
            cout<<endl;
        }
    }
    find_min(int *dis)
    {
        int d=INT_MAX;
        int index=0;
        for(int i=0;i<nodes;i++)
        {
            if(d>dis[i]&&status[i]!=true)
            {
                d=dis[i];
                index=i;
            }
        }
        return index;
    }
    void dijsktra()
    {
        for(int i=0;i<nodes;i++)
            dis[i]=INT_MAX;
        dis[0]=0;
        for(int i=0;i<nodes;i++)
        {
            int min_vertex=find_min(dis);
            status[min_vertex]=true;
            for(int j=0;j<nodes;j++)
            {
                if(adj[min_vertex][j]!=INT_MAX&&dis[min_vertex]+adj[min_vertex][j]<dis[j])
                    dis[j]=dis[min_vertex]+adj[min_vertex][j];
            }
        }
    }
    void show_ans()
    {
        cout<<"solution : \n";
        cout<<setw(5)<<"node"<<setw(5)<<"dis"<<endl;
        for(int i=0;i<nodes;i++)
        {
            cout<<setw(5)<<i;
            if(dis[i]!=INT_MAX)
            cout<<setw(5)<<dis[i]<<endl;
            else
                cout<<setw(5)<<"inf"<<endl;
        }
    }

};
int main()
{
    graph g;
    g.show();
    g.dijsktra();
    g.show_ans();
    return 0;
}
OUTPUT:

TIME COMPLEXITY:
Number of nodes to be relaxed : N
Max number of nodes to be relaxed in each turn(n turns )=N
Total complexity : O(N*N)

Experiment-5
Aim:- WAP to implement the breadth & depth first search and fractional knapsack algorithm, also
discuss the time complexity of algorithm.
Theory:-
Breadth first search : Breadth First Search is a recursive algorithm for searching all the vertices of a
graph or tree data structure. We start this algorithm by putting any one of the graph's vertices at the
back of a queue. Take the front item of the queue and add it to the visited list. Create a list of that
vertex's adjacent nodes. Add the ones which aren't in the visited list to the back of the queue. Keep
repeating steps 2 and 3 until the queue is empty.
Depth first Search : Depth first Search or Depth first traversal is a recursive algorithm for searching
all the vertices of a graph or tree data structure. Traversal means visiting all the nodes of a graph
while avoiding cycles. We start this algorithm by putting any one of the graph's vertices on top of a
stack. Take the top item of the stack and add it to the visited list. Create a list of that vertex's adjacent
nodes. Add the ones which aren't in the visited list to the top of the stack. Keep repeating steps 2 and
3 until the stack is empty.
Fractional Knapsack : this problem there will have given some profit and weight and also there will
be a constraint that I can't take more weight than that. How we can maximize profit from this
restriction is our main task of this problem. Compute the profit/weight for each item. Obeying a
Greedy Strategy, we take as possible of the item with the highest ratio. If the supply of that element is
exhausted and we can still carry more, we take as much as possible of the element with the next ratio.

DEPTH FIRST SEARCH


#include<bits/stdc++.h>
using namespace std;

class graph
{
    int nodes,edges;
    vector<vector<int>>adj;
    vector<int>dfs;
    bool *status;
public:
    graph()
    {
        cout<<"nodes : ";
        cin>>nodes;
        cout<<"edges : ";
        cin>>edges;
        for(int i=0;i<nodes;i++)
            adj.push_back(vector<int>());
        status=new bool[nodes];
        memset(status,false,nodes);
        cout<<"enter edges :\n";
        for(int i=0;i<edges;i++)
        {
            int s,d;
            cin>>s>>d;
            adj[s].push_back(d);
        }
    }
    void dfs1()
    {
        stack<int>s;
        for(int i=0;i<nodes;i++)
        {
            if(adj[i].size())
            {
                s.push(i);
                status[i]=true;
                break;
            }
        }

        while(!s.empty())
        {
            int temp=s.top();
            s.pop();
            for(int i=0;i<adj[temp].size();i++)
            {
                if(status[adj[temp][i]]==false)
                {
                    s.push(adj[temp][i]);
                    status[adj[temp][i]]=true;
                }
            }
            dfs.push_back(temp);
        }
    }
    void show()
    {
        cout<<"result : ";
        for(int i=0;i<dfs.size();i++)
            cout<<dfs[i]<<" ";
    }
};

int main()
{
    graph g;
    g.dfs1();
    g.show();
    return 0;
}

OUTPUT:
TIME COMPLEXITY:
We need to traverse all the edges so time complexity : O(v)
Where v=number of vertices

BREADTH FIRST SEARCH


#include<bits/stdc++.h>
using namespace std;
class graph
{
    int nodes,edges;
    vector<vector<int>>adj;
    vector<int>bfs;
    bool *status;
public:
    graph()
    {
        cout<<"nodes : ";
        cin>>nodes;
        cout<<"edges : ";
        cin>>edges;
        for(int i=0;i<nodes;i++)
            adj.push_back(vector<int>());
        status=new bool[nodes];
        memset(status,false,nodes);
        cout<<"enter edges :\n";
        for(int i=0;i<edges;i++)
        {
            int s,d;
            cin>>s>>d;
            adj[s].push_back(d);
        }
    }
    void bfs1()
    {
        queue<int>q;
        for(int i=0;i<nodes;i++)
        {
            if(adj[i].size())
            {
                q.push(i);
                status[i]=true;
                break;
            }
        }
        while(!q.empty())
        {
            int temp=q.front();
            q.pop();
            for(int i=0;i<adj[temp].size();i++)
            {
                if(status[adj[temp][i]]==false)
                {
                    q.push(adj[temp][i]);
                    status[adj[temp][i]]=true;
                }
            }
            bfs.push_back(temp);
        }
    }
    void show() {
        cout<<"result : ";
        for(int i=0;i<bfs.size();i++)
            cout<<bfs[i]<<" ";
    }
};
int main()
{
    graph g;
    g.bfs1();
    g.show();
    return 0;}

OUTPUT:

TIME COMPLEXITY:
We need to traverse all the edges so time complexity : O(v)
Where v=number of vertices

FRACTIONAL KNAPSACK:
#include<bits/stdc++.h>
using namespace std;

struct obj
{
    float weight,cost,ratioo,index;
};

bool cmp(obj a,obj b)


{
    return(a.ratioo>b.ratioo);
}

int main()
{
    int n;
    cout<<"enter the number of objects : ";
    cin>>n;
    cout<<"enter cost and weight :\n";
    obj a[n];
    for(int i=0;i<n;i++)
    {
        cin>>a[i].cost>>a[i].weight;
        a[i].ratioo=a[i].cost/a[i].weight;
        a[i].index=i;
    }
    sort(a,a+n,cmp);

    float cap;
    cout<<"enter the capacity : ";
    cin>>cap;
    vector<pair<int,float>>sol;
    int i=0;
    int total_cost=0;

    while(cap&&i<n)
    {
        float w=min(cap,a[i].weight);
        float c;
        if(w!=a[i].weight)
            c=a[i].ratioo*w;
        else
            c=a[i].cost;
        sol.push_back({c,w});
        cap=cap-w;
        i++;
        total_cost=total_cost+c;
    }
    cout<<"solution : \n";
    cout<<setw(5)<<"cost"<<setw(5)<<"wt"<<endl;
    for(int i=0;i<sol.size();i++)
        cout<<setw(5)<<sol[i].first<<setw(5)<<sol[i].second<<endl;
    cout<<endl<<"total cost : "<<total_cost<<endl;
    return 0;
}

OUTPUT:

TIME COMPLEXITY:
First we need to sort the weights in the decreasing order of their cost by weight ratios => O(n log n)
Now we need to select elements from array =>O(n)
Total complexity : O(n+ n log n)
=>O(nlogn)
Experiment-6
Aim:- WAP to implement an activity-selection problem and job sequencing with deadline.
Theory:-

Activity-selection problem : In this there are n different activities given with their starting time and
ending time and we have to select maximum number of activities to solve by a single person. We will
use the greedy approach to find the next activity whose finish time is minimum among rest activities,
and the start time is more than or equal with the finish time of the last selected activity.

Job sequencing with deadline : In this we are given n jobs with their deadlines and corresponding
profits. We have to select the jobs in such a sequence such that we get a maximum profit. Sort all the
jobs by decreasing order of profit. Initializing the result sequence as the first job in sorted the jobs. Do
following for remaining n-1 jobs that If the current job can fit in the current slot without missing the
deadline, add the current job to the result. Else reject the current job.

JOB SEQUENCING:
#include<bits/stdc++.h>
using namespace std;
bool cmp(pair<int,int>a,pair<int,int>b)
{
    return a.first>b.first;
}
int main()
{
    int n;
    cout<<"enter number of jobs : ";
    cin>>n;
    cout<<"enter profits and deadlines : \n";
    vector<pair<int,int>>v;
    for(int i=0;i<n;i++)
    {
        int d,p;
        cin>>p>>d;
        v.push_back({p,d});
    }

    sort(v.begin(),v.end(),cmp);
    vector<int>temp;
    for(int i=0;i<=n;i++)
        temp.push_back(1);

    vector<pair<int,int>>result;
    for(int i=0;i<n;i++)
    {
        int k=v[i].second;
        while(k>0&&temp[k]==0)
            k--;
        if(k)
        {
            result.push_back(v[i]);
            temp[k]--;
        }
    }

    cout<<"result \n";
    int profit=0;
    for(int i=0;i<result.size();i++)
    {
        cout<<setw(5)<<result[i].first<<setw(5)<<result[i].second<<endl;
        profit+=result[i].first;
    }
    cout<<"total profit : "<<profit;
}

OUTPUT:

Time complexity:
Time taken to sort the jobs in descending order of their profits :O( n Log n)
Time to select jobs according to avaiExperimentle sort in worst case : O(n*n)
Hence total time complexity : O(n Log n +n*n)
                                             =>O(n*n)

ACTIVITY SELECTION:
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cout<<"enter number of activities : ";
    cin>>n;
    cout<<"enter start and finish time :\n";
    vector<pair<int,int>>v;
    for(int i=0;i<n;i++)
    {
        int s,f;
        cin>>s>>f;
        v.push_back({s,f});
    }
    vector<pair<int,int>>result;
    sort(v.begin(),v.end());
    int i=0;
    int st=0;
    while(i<n)
    {
        while(i<n&&st>v[i].first)
            i++;
        if(i<n)
        {
            result.push_back(v[i]);
            st=v[i].second;
            i++;
        }
    }
    cout<<"result : \n";
    int sum=0;
    for(int i=0;i<result.size();i++)
        cout<<setw(5)<<result[i].first<<" "<<setw(5)<<result[i].second<<endl;
     cout<<"total number of activities : "<<result.size();
}

OUTPUT:

Time complexity:
To sort the activities according to their start time : O(n log n)
To check all the activities if they could be started after the end of current on going activity : O(n)
Total time complexity : O(n + n Log n)
Experiment-7

Aim:- WAP to implement Huffman codes with the help of example, also discuss the time complexity
of algorithms.

Theory:

Huffman Code : It is a compression technique to reduce the size of the data or message to be
transferred. It is generally useful to compress the data in which there are frequently occurring
characters. It uses variable size coding and optimal merge pattern to give codes to the characters
according to their frequency. We use min heap to arrange the characters in order of their frequency.

HUFFMAN CODE:
#include<bits/stdc++.h>
using namespace std;
struct tree
{
    int val;
    char c;
    tree *left,*right;
    tree(int val,char c=0)
    {
        this->val=val;
        this->c=c;
        left=nullptr;
        right=nullptr;
    }
};
class cmp
{
public:
    bool operator ()(tree const *a,tree const *b)
    {
        return(a->val>b->val);
    }
};
tree *root=nullptr;
priority_queue<tree*,vector<tree*>,cmp> pq;
void insrt(int val,char c)
{
    tree *t=new tree(val,c);
    pq.push(t);
}

map<char,string>codes;
void solve(tree *node,string output)
{
    if(node==nullptr)
        return;
    if(node->left==nullptr&&node->right==nullptr)
    {
        codes[node->c]=output;
        return;
    }
    solve(node->left,output+'0');
    solve(node->right,output+'1');
}
void get_codes()
{
    solve(root,"");
}

string code_huffman(string s)
{
    map<char,int>m;
    for(auto it:s)
        m[it]++;
    for(auto it:m)
        insrt(it.second,it.first);
    while(pq.size()>1)
    {
        tree *temp1=pq.top();
        pq.pop();
        tree *temp2=pq.top();
        pq.pop();
        tree *t=new tree(temp1->val+temp2->val);
        t->left=temp1;
        t->right=temp2;
        pq.push(t);
    }
    tree *t1=pq.top();
    root=t1;
    pq.pop();
    get_codes();
    string result;
    for(auto it:s)
        result+=codes[it];
    return result;
}
void decode_huffman(string str)
{
    string result="";
    int i=0;
    int n=str.length();
    while(i<n)
    {
        tree *node=root;
        while(node!=nullptr&&i<n)
        {
            if(str[i]=='1')
                node=node->right;
            else
                node=node->left;
            if(node->c!=0)
            {
                result+=node->c;
                i++;
                break;
            }
            i++;
        }
    }
    cout<<"decoded string is : "<<result<<endl;
}
int main()
{
    cout<<"enter string : ";
    string s;
    getline(cin,s);
    cout<<"coded string is : "<<code_huffman(s)<<endl;
    cout<<"enter string to decode : ";
    string str;
    cin>>str;
    decode_huffman(str);
}

OUTPUT:

TIME COMPLEXITY:
Complexity to get frequency of each character : O(n)
To make tree : O(d)  where d=number of distinct characters
As we know priority queue is internally implemented as a min or max heap 
So time for inserting and deleting n elements =O(nlogn+nlogn)
                                                                       =>O(2* n log n)
                                                                       =>O(n log n)
To get the coded string from tree : O(n)
Total time complexity : O(n+n log n+n)
                                =>O(n log n)
To decode :
Time complexity to get one character : O(log n)
Total time complexity : O(n log n)
Experiment-8
Aim:- WAP to implement the Matrix chain multiplication and assembly line scheduling algorithm
and analyse the time complexity of algorithm.
Theory:-
Matrix chain multiplication : In the matrix-chain multiplication problem, we are not actually
multiplying matrices. Our goal is only to determine an order for multiplying matrices that has the
lowest cost. This method follows dynamic approach.

Assembly scheduling algorithm : In this problem we need to start from one of the assembly lines and
then at each point we have two options whether to switch to other assembly line or stay on the same
line. Thus, basically if we are at a particular station say Sij then we can determine the time taken by
simply adding aij to the previous station cost.

MATRIX CHAIN MULTIPLICATION:


#include<bits/stdc++.h>
using namespace std;

struct matrix
{
    int row,column;
};

string parenthesis(int low,int high,int **arr)


{
    if(low==high)
        {
            string s="";
            s=s+'A'+char(low+48);
            return s;
        }
    int k=arr[low][high];
    string p1=parenthesis(low,k,arr);
    string p2=parenthesis(k+1,high,arr);
    return('('+p1+'*'+p2+')');
}

int main()
{
    int n;
    cout<<"enter no. of matrices : ";
    cin>>n;
    matrix M[n];
    cout<<"enter orders :\n";
    for(int i=0;i<n;i++)
        cin>>M[i].row>>M[i].column;
    int cost[n][n]={0};
    int **arr=new int*[n];

    for(int i=0;i<n;i++)
    {
        arr[i]=new int[n];
        memset(arr[i],0,n*4);
    }

    for(int i=0;i<n;i++)
        arr[i][i]=i;

    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<n-i;j++)
        {
            int costt=INT_MAX;
            int index=j;

            for(int k=j+1;k<=j+i;k++)
            {
                int c=M[j].row*M[k-1].column*M[j+i].column+cost[j][k-1]+cost[k][j+i];
                costt=min(costt,c);
                index=costt==c?k-1:index;
            }
            cost[j][j+i]=costt;
            arr[j][j+i]=index;
        }
    }

    cout<<"cost:\n";

    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
            cout<<setw(5)<<cost[i][j]<<" ";
        cout<<endl;
    }

    cout<<endl<<"index :\n";

    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
            cout<<setw(5)<<arr[i][j]<<" ";
        cout<<endl;
    }

    cout<<"string : "<<parenthesis(0,n-1,arr);
}

OUTPUT:
TIME COMPLEXITY:
We have n matrices to multiply,it will take O(n) time to generate each of the O(n^2) costs and entries
in the best matrix.
Total time complexity : O(n^3)

ASSEMBLY LINE SCHEDULING:


#include<bits/stdc++.h>
using namespace std;
void find_path(vector<vector<int>>&pos,int n,int t)
{
    if(n<0)
        return;
    find_path(pos,n-1,pos[t][n]);
    cout<<t<<"->";
}
int main()
{
    int n;
    cout<<"enter number of stations : ";
    cin>>n;
    int arry[2][n];
    cout<<"enter values \n";
    for(int i=0;i<2;i++)
    {
        cout<<"line "<<i<<endl;
        for(int j=0;j<n;j++)
            cin>>arry[i][j];
    }
    cout<<"enter distance cost :\n";
    int dis[2][n];
    for(int i=0;i<2;i++)
    {
        cout<<"line "<<i<<endl;
        for(int j=0;j<n;j++)
            cin>>dis[i][j];
    }

    int dp[2][n];
    cout<<"enter cost for first station in each line \n";
    for(int i=0;i<2;i++)
    {
        cin>>dp[i][0];
        dp[i][0]+=arry[i][0];
    }
    vector<vector<int>>pos(2,vector<int>(n));
    pos[0][0]=0;
    pos[1][0]=1;
    for(int i=1;i<n;i++)
    {
        dp[0][i]=min(dp[0][i-1],dp[1][i-1]+dis[1][i-1])+arry[0][i];
        pos[0][i]=dp[0][i-1]<dp[1][i-1]+dis[1][i-1]?0:1;
        dp[1][i]=min(dp[1][i-1],dp[0][i-1]+dis[0][i-1])+arry[1][i];
        pos[1][i]=dp[1][i-1]<dp[0][i-1]+dis[0][i-1]?1:0;
    }
    int min_cost=min(dp[0][n-1]+dis[0][n-1],dp[1][n-1]+dis[1][n-1]);
    int t=dp[0][n-1]+dis[0][n-1]<dp[1][n-1]+dis[1][n-1]?0:1;
    cout<<"\ntotal_cost : "<<min_cost<<endl;
    cout<<"path :\n";
    find_path(pos,n-1,t);
}

OUTPUT:
TIME COMPLEXITY:
For each line we check the previous weights of one node and have to traverse through the list to check
it for each node.
So, time complexity: O(n)
Experiment-9
Aim:- WAP to implement the Longest common subsequence and 0/1 Knapsack algorithm and analyse
the time complexity of algorithm.
Theory:

Longest Common Subsequence Algorithm : The longest common subsequence (LCS) is defined as the
longest subsequence that is common to all the given sequences, provided that the elements of the
subsequence are not required to occupy consecutive positions within the original sequences. Suppose,
X and Y are two sequences over a finite set of elements. We can say that Z is a common subsequence
of X and Y, if Z is a subsequence of both X and Y.

0/1 Knapsack Problem : Knapsack is basically means a bag of given capacity. The knapsack problem
where we have to pack the knapsack with maximum value in such a manner that the total weight of
the items should not be greater than the capacity of the knapsack. In this item cannot be broken which
means Each item is taken or not taken and cannot take a fractional amount of an item taken or take an
item more than once.

LONGEST COMMON SUBSEQUENCE:


#include<bits/stdc++.h>
using namespace std;
string s1,s2;
map<string,int>m;
void get_string(vector<vector<int>>dp,int i,int j,string output)
{
    if(i==0||j==0)
    {
        if(m[output]==0)
            m[output]++;
        return;
    }
    if(s1[i-1]==s2[j-1])
        get_string(dp,i-1,j-1,s1[i-1]+output);

    else if(dp[i-1][j]>dp[i][j-1])
        get_string(dp,i-1,j,output);

    else if(dp[i-1][j]<dp[i][j-1])
        get_string(dp,i,j-1,output);

    else
    {
        get_string(dp,i-1,j,output);
        get_string(dp,i,j-1,output);
    }

}
int main()
{
    cout<<"enter two strings : ";
    cin>>s1>>s2;
    vector<vector<int>>dp(s1.length()+1,vector<int>(s2.length()+1,0));
    for(int i=1;i<=s1.length();i++)
    {
        for(int j=1;j<=s2.length();j++)
        {
            if(s1[i-1]==s2[j-1])
                dp[i][j]=dp[i-1][j-1]+1;
            else
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        }
    }

    cout<<"length of largest subsequence  : "<<dp[s1.length()][s2.length()]<<endl;


    int i=s1.length();
    int j=s2.length();
    string s="";
    get_string(dp,i,j,s);
    cout<<"sub-sequences are : \n";
    map<string,int>::iterator itr=m.begin();
    while(itr!=m.end())
    {
        cout<<itr->first<<endl;
        itr++;
    }
    return 0;
}

OUTPUT:

TIME COMPLEXITY:

We need to check every character of second string for each character of first string to keep the track of
number of characters upto that character that contribute to longest common subsequence.

So time complexity: O(n*n)

0/1 KNAPSACK PROBLEM


#include<bits/stdc++.h>
using namespace std;
struct object
{
    int weight,value;
};
bool cmp(object a,object b)
{
    return(a.weight<b.weight);
}
int main()
{
    int n;
    cout<<"enter number of objects : ";
    cin>>n;
    object obj[n+1];
    obj[0].weight=0;
    obj[0].value=0;
    cout<<"enter the weight and values : \n";
    for(int i=1;i<=n;i++)
        cin>>obj[i].weight>>obj[i].value;

    cout<<"enter capacity : ";


    int cap;
    cin>>cap;
    int dp[n+1][cap+1];
    memset(dp,0,sizeof(dp));

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=cap;j++)
        {
            if(obj[i].weight<=j)
            {
                dp[i][j]=max(dp[i-1][j],obj[i].value+dp[i-1][j-obj[i].weight]);
            }
            else
            dp[i][j]=dp[i-1][j];
        }
    }
    int i=n;
    int j=cap;
    vector<int>v;
    while(i>0&&j>0)
    {
        if(dp[i][j]!=dp[i-1][j])
        {
            v.push_back(obj[i].weight);
            j=j-obj[i].weight;
        }
        i--;
    }
    cout<<"maximum profit : "<<dp[n][cap]<<endl;
    cout<<"elements : ";
    for(int i=0;i<v.size();i++)
        cout<<v[i]<<" ";
}

OUTPUT:
TIME COMPLEXITY:
We check each object for all the possible weights that can be accommodated in the target weight and
maximise profit foe each entry in the table .
Time complexity: O(n*n)
Experiment-10
Aim:- WAP to implement the Optimal binary search trees and all pair shortest path algorithm(Floyd-
Warshall algorithm) and analyse the time complexity of algorithm.
THEORY:-
Optimal binary search tree : A set of integers are given in the sorted order and another array freq to
frequency count. Our task is to create a binary search tree with those data to find the minimum cost
for all searches.
FLOYD WARSHALL ALGORITHM : It is used for solving all pairs shortest path problem. It helps
to find out the shortest distances between every pair of vertices in a given graph. This algorithm
works for both the directed and undirected weighted graphs. But it does not work for the graphs with
negative cycles (where the sum of the edges in a cycle is negative).

OPTIMAL BINARY SEARCH TREE:


#include<bits/stdc++.h>
using namespace std;
struct node
{
int val;
int s_prob;
};
node *obj;

int get_min(int low,int high,vector<vector<int>>&root,vector<vector<int>>&cost)


{
if(low==high)
return cost[low][high]=obj[low].s_prob;
if(low>high)
return 0;

int res=INT_MAX;
int r=low;
for(int i=low;i<=high;i++)
{
int k1=get_min(low,i-1,root,cost);
int k2=get_min(i+1,high,root,cost);
if(res>k1+k2)
{
res=k1+k2;
r=i;
}
}
for(int i=low;i<=high;i++)
{
res=res+obj[i].s_prob;
}
root[low][high]=r;
return cost[low][high]=res;
}
bool cmp(node a,node b)
{
return(a.val<b.val);
}
int main()
{
int n;
cout<<"enter number of nodes : ";
cin>>n;
obj=new node[n];

vector<vector<int>>cost(n,vector<int>(n,0));

cout<<"enter weights and probability : \n";


for(int i=0;i<n;i++)
cin>>obj[i].val>>obj[i].s_prob;

sort(obj,obj+n,cmp);

vector<vector<int>>root(n ,vector<int>(n,0));

cout<<"minimum cost is : "<<get_min(0,n-1,root,cost)<<endl;


cout<<"cost matrix :\n";
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
cout<<setw(5)<<cost[i][j]<<" ";
cout<<endl;
}
cout<<"\nroots :\n";
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
cout<<setw(5)<<root[i][j]<<" ";
cout<<endl;
}
}

OUTPUT:

TIME COMPLEXITY:
 Algorithm require O(n*n*n) time as it involves 3 nested for loops which requires O(n) time each.

Floyd-Warshall algorithm
#include<iostream>
#define inf 99999
#include<iomanip>
using namespace std;

class graph
{
    int nodes;
    int edges;
    int **adj;
public:
    graph()
    {
        cout<<"enter the number of nodes:";
        cin>>nodes;
        cout<<"enter the number of edges:";
        cin>>edges;
        adj=new int*[nodes];
        for(int i=0;i<nodes;i++)
            adj[i]=new int[nodes];
        for(int i=0;i<nodes;i++)
        {
            for(int j=0;j<nodes;j++)
            {
                if(i==j)
                    adj[i][j]=0;
                else
                    adj[i][j]=inf;
            }
        }
    }

    void flloyd()
    {
        int s,d,dis;

        for(int i=0;i<edges;i++)
        {
            cin>>s>>d>>dis;
            adj[s-1][d-1]=dis;
        }
        for(int k=0;k<nodes;k++)
                for(int i=0;i<nodes;i++)
                    for(int j=0;j<nodes;j++)
                    if(adj[i][k]!=inf &&adj[k][j]!=inf &&adj[i][j]>adj[i][k]+adj[k][j])
                        adj[i][j]=adj[i][k]+adj[k][j];
    }

    void show()
    {
        cout<<"    ";
        for(int i=0;i<nodes;i++)
            cout<<setw(4)<<left<<i;
        cout<<endl;
        for(int i=0;i<nodes;i++)
        {
            cout<<setw(4)<<left<<i;
            for(int j=0;j<nodes;j++)
                {
                    if(adj[i][j]==inf)
                        cout<<setw(4)<<left<<"inf";
                    else
                        cout<<setw(4)<<left<<adj[i][j];
                }
            cout<<endl;
        }
        cout<<endl<<endl;
    }
};

int main()
{
    graph g;
    g.flloyd();
    g.show();
    return 0;
}

OUTPUT:

TIME COMPLEXITY:
 Algorithm require O(n*n*n) time as it involves 3 nested for loops which requires O(n) time each.
Experiment-11

Aim:-Given an array, find a Subarray with consecutive elements and maximum sum. Negative
numbers allowed.

#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cout<<"number of elements : ";
cin>>n;
int arry[n];
cout<<"elements : \n";
for(int i=0;i<n;i++)
{
cin>>arry[i];
}
int global_len=0;
int global_max=0;
int local_max=0;
int local_len=0;
int st,ed;
for(int i=0;i<n;i++)
{
if(local_max+arry[i]>=arry[i])
{
local_len++;
local_max=local_max+arry[i];
}
else
{
local_len=1;
local_max=arry[i];
}
if(local_max>global_max)
{
global_max=local_max;
global_len=local_len;
st=i-global_len+1;
ed=i;
}
}
cout<<"elements : \n";
for(int i=st;i<=ed;i++)
{
cout<<arry[i]<<" ";
}
cout<<endl;
cout<<"length : "<<global_len<<endl;
cout<<"sum : "<<global_max<<endl;
}

You might also like