Home > Net >  c selection sort with separate minimum index function
c selection sort with separate minimum index function

Time:04-20

Hi I'm doing a problem for my c class where we are to create a generic selection sort function for all types with separate function that finds minimum index. I tried to modify selection sort function that uses two for loops by separating the two for loops into two separate functions. I tried different ways to approach this problem but I just don't get what I am doing wrong. Please help.

#include <vector>
#include <random>
#include <iostream>
#include<stdexcept>
#include<time.h>
#include <valarray>

using namespace std;

template <typename T>
unsigned min_index(const vector<T> &vals, unsigned index){
    auto min = index;
    for(auto i = index  1; i != vals.end();i  ){
        if(*i < *min)
            min = i;
    }
    return min;
}

template <typename T>
void selection_sort(vector<T> &vals){
    for(auto i=vals.begin(); i!=vals.end(); i  ){
        auto min = min_index(vals, i);
        swap(*i, *min);
    }
}

CodePudding user response:

You're trying to develop a positional-index based min_index (which is dreadfully broken itself), then use it within an iterator-based selection sort.

template <typename T>
unsigned min_index(const vector<T> &vals, unsigned index)
{
    auto min = index; // min is 'unsigned' like 'index'

    // this loop is nonsense.
    //  'i' is unsigned (because 'index' is unsigned)
    //  'vals.end()' is an iterator, not an unsigned, therefore...
    //  'i != vals.end()` is nonsense.
    //  'min' is also unsigned, therefore...
    //  both *i and *min are nonsense.
    for(auto i = index  1; i != vals.end();i  )
    { 
        if(*i < *min)
            min = i;
    }
    return min;
}

Later on, in your selection-sort...

template <typename T>
void selection_sort(vector<T> &vals){
    // here 'i' is an iterator
    for(auto i=vals.begin(); i!=vals.end(); i  )
    {
        // here you're trying to pass an iterator to a function
        // expecting an unsigned. 
        auto min = min_index(vals, i);

        // and the above function is returning an unsigned
        // therefore *min is nonsense.
        swap(*i, *min);
    }
}

In short, neither of those functions can possibly compile, much less work.


You need to choose one or the other and stick with it. This is C , so the easiest to implement is likely an iterator version. As a bonus, it also ends up being the most generic (there are iterators literally everywhere in modern C ). For example, the min_index, rewritten as min_iter, could look like this:

template<class Iter>
Iter min_iter(Iter beg, Iter end)
{
    auto min = beg;
    for (; beg != end;   beg)
    {
        if (*beg < *min)
            min = beg;
    }
    return min;
}

Now you can use that in an iterator-based selection-sort as well:

template <class Iter>
void selection_sort(Iter beg, Iter end)
{
    for (; beg != end;   beg)
        std::iter_swap(beg, min_iter(beg, end));
}

And finally, you can front this with a generic sequence abstraction by utilizing the general std::begin and std::end functions from the standard library:

template<class Seq>
void selection_sort(Seq& seq)
{
    selection_sort(std::begin(seq), std::end(seq));
}

Now you can pass a vector, a deque, an array, etc. Pretty much any sequence container instance will work, so long as the underlying element type supports operator < either natively or by overload.

CodePudding user response:

so this is what I have right now and the code is compiling. But when I ran a vector with {5, 3, 2, 1, 4} I just get 3.

   template <typename T>
    unsigned min_index(const vector<T> &vals, unsigned index){
        T min = vals[index];
        for(unsigned i = index  1; i < vals.size();i  ){
            if(vals[i] < min)
                min = vals[i];
        }
        
        return min;
    }
    
    template <typename T>
    void selection_sort(vector<T> &vals){
        for(unsigned i=0; i < vals.size();  i  ){
            unsigned min = min_index(vals, i);
            T temp = vals[i];
            vals[i] = vals[min];
            vals[min] = temp;
        }
    }
  • Related