#include <iostream>

using namespace std;

typedef pair<double*,int>(*TFunc)(double* a, int n);


pair<double*,int> bubblesort(double* a, int n);
pair<double*,int> vibor(double* a, int n);
void sort(double* a, int n, TFunc f);

ostream& operator<< (ostream& os, const pair<double*,int>& p)
{
    for(int i = 0; i < p.second; ++i)
        os << p.first[i] << "\t";
    return os << endl;
}

TFunc menu();

int main()
{
    TFunc item;
    int n;
    cout << "Enter the amount of elements in array --> " << endl;
    cin >> n;
    double* a = new double[n];
    cout << "Array before selecting a way to sort:\n";
    for (int i = 0; i < n; i++)
    {
        cout << i + 1 << "-ый элемент: ";
        cin >> a[i];
    }
    for (int i = 0; i < n; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;

    item = menu();
    if (item == NULL)
    {
        cout << "Function number is entered incorrectly!";
    }
    else
    {
        sort(a, n, item);
    }
    delete[] a;
}

pair<double*,int> bubblesort(double* a, int n)
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n - 1; j++)
        {
            if (a[j] < a[j + 1])
            {
                double temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
    return make_pair(a,n);
}

pair<double*,int> vibor(double* a, int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        int biggestIndex = i;
        for (int j = i + 1; j < n; j++)
        {
            if (a[j] > a[biggestIndex])
            {
                biggestIndex = j;
            }
        }
        swap(a[i], a[biggestIndex]);
    }
    return make_pair(a,n);
}

void sort(double* a, int n, TFunc f)
{
    cout << f(a, n);
}

TFunc menu()
{
    TFunc fun_items[] = { bubblesort, vibor };
    int key;
    cout << "Selecting a way to sort array:\n"
        "1 - bubblesort, 2 - vibor\n";
    cin >> key;
    switch (key)
    {
    case 1:;
    case 2: return fun_items[key - 1];
    default: return NULL;
    }
}
