-1

I was curious about how much difference occured when if I implement a code to find max elelment of a vector and I've used two functions: one of them uses divide and conquer algorithm and other uses normal recursion. At the first glance, I thought that divide and conquer algorithm is less efficient than other because it generates temporary variables, it has more comparisons than other and more. However, when I test both of them results are completely different from my ideas. The codes and results are below:

// Divide and conquer
#include <bits/stdc++.h>
#define maxi 100000
long int c = 0; // counter for number of function cals
using namespace std;
using namespace std::chrono;

int find_max (vector<int> &a, int l, int r){
    ++c;
    if (l == r){
        return a[l];
    }
    int m = (l+r)/2;
    int u = find_max(a,l,m);
    int v = find_max(a,m+1,r);
    if(u > v)
        return u;
    else 
        return v;
}

int main(){
    srand(time(NULL));
    vector<int> a;
    for (int i = 0; i < maxi; ++i){
        int b = rand() % maxi + 1;
        a.push_back(b);
    }
    auto start = high_resolution_clock::now();
    cout << find_max(a, 0, maxi-1) << endl;
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);
    cout << "Time taken by function: " << duration.count() << " microseconds" << endl;
    cout << "counter: " << c << endl;
}

Results of divide and conquer algorithm

// Linear recursion
#include <bits/stdc++.h>
#define maxi 100000
long int c = 0;
using namespace std;
using namespace std::chrono;

int find_max (vector<int> &a, int i){
    ++c;
    if (i == 1){
        return a[0];
    }
    return max(a[i-1], find_max(a, i-1));
}

int main(){
    srand(time(NULL));
    vector<int> a;
    for (int i = 0; i < maxi; ++i){
        int b = rand() % maxi + 1;
        a.push_back(b);
    }
    auto start = high_resolution_clock::now();
    cout << find_max(a, a.size()) << endl;
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);
    cout << "Time taken by function: " << duration.count() << " microseconds" << endl;
    cout << "counter: " << c << endl;
}

Results of linear recursion algorithm

What is the reason of this difference, what do you think? Thanks in advance.

MyZeths
  • 1
  • 2
  • Have you checked the compiler even generates different code? – Goswin von Brederlow Jul 24 '22 at 15:15
  • You linked twice to the same image. However, it's not clear why it has to be an image in the first place. Would it be too hard to copy/paste the text into the question? – Igor Tandetnik Jul 24 '22 at 15:19
  • 2
    The results are text, copy and paste them into your question. Do not embed images of text, as per the help section of the site. – pjs Jul 24 '22 at 15:21
  • I have attended site today and this is my first entry. Thanks for advices. – MyZeths Jul 24 '22 at 21:28
  • In both cases, the memory usage should be small and constant. Recursion is a waste of resources here. – Pete Becker Jul 24 '22 at 23:27
  • But if I increase number of elements (maxi constant), still divide and conquer consumes less memory and is faster than other. Why do you think that divide and conquer is wasteful? – MyZeths Jul 25 '22 at 09:06
  • Because a simple loop will use no extra memory and avoid function calls. There is no need to be recursive at all. – Goswin von Brederlow Jul 25 '22 at 11:37
  • I have just tried using simple loop, but according to online compiler memory usage of simple loop virtually same with divide and conquer. – MyZeths Jul 25 '22 at 13:52

1 Answers1

1

If the compiler doesn't optimize this then your divide&conquer needs O(log n) space and your linear needs O(n) space. So quite the opposite of what you thought.

As for the number of comparisons: Obviously they are both the same. Imagine you have a binary tree with N leaves. That has N - 1 inner nodes and every inner node is a compare. Doesn't matter if it is balanced (divide&conquer) or slanted all to one side (linear). It's always the same number of leaves and inner nodes, aka comparisons.

Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42
  • Thanks for your answer, I am first grade student, so I haven't got the ideas properly. I will try to understand this answer and more. – MyZeths Jul 24 '22 at 21:30