bubble sort using pointers - c++

not sure if I'm doing this right, or even if I'm allowed to sort using pointers. I made a structure that has pointers to other elements. Then made a vector of this structure, and tried to do some swaps on it.
At first I used dereference operators on the swap operation, but when I did, my sorts were turning out weird, I was getting a bunch of duplicate #'s in the end results (they should all be unique), pulling the dereference off solved this, but it wasn't sorting (unless maybe by memory address).
So here is my code, the area of concern is with the sortSuperStruct function
#include <algorithm> //used for swap, would like to use for sort, but oh well
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
//#include <math.h>
#include <string>
#include <sstream>
#include <vector>
//------------------------------------------------------------------------------
//namespaces?
//------------------------------------------------------------------------------
using namespace std;
//------------------------------------------------------------------------------
//prototypes
//------------------------------------------------------------------------------
struct superStruct
{
//probably not needed
float *percent;
//copy of Dwarf's role pPercent;
float *pPercent;
int *roleName;
int *name;
};
//parallel array to follow along with Dwarf role
struct roles
{
int name;
float priority;
int numberToAssign;
void setRolePriorities ()
{
priority = (float)rand()/(float)RAND_MAX;
}
void setNumberToAssign(int n)
{
numberToAssign = rand() % n + 1;
}
};
//a fit for a role, a Dwarf has this
struct role
{
float percent;
//copy of roles name
int *roleName;
//copy of roles priority
float *rolePriority;
float pPercent;
void set_pPercent()
{
pPercent = percent * (*rolePriority);
};
};
struct Dwarf
{
vector <role> roleValues;
int *maxLabor;
int name;
void setRoleValues(int n, vector <roles> *roleS)
{
srand ( time(NULL) );
//rolesValues
roleValues.resize(n);
//set role %'s
for (int x = 0; x < n; x++)
{
roleValues[x].percent = (float)rand()/(float)RAND_MAX;
//cout << roleValues[x].percent << endl;
//I said I'm pointing to the address value of roleS...
roleValues[x].roleName = &roleS->at(x).name;
roleValues[x].rolePriority = &roleS->at(x).priority;
roleValues[x].set_pPercent();
}
};
};
void initializeSuperStruct(vector <superStruct> *s, vector <Dwarf> *d, int n)
{
//for each Dwarf
int counter = 0;
for (int x = 0; x < d->size(); x++)
{
//for each role
for (int y = 0; y < n; y++)
{
s->at(counter).pPercent = &d->at(x).roleValues[y].pPercent;
s->at(counter).name = &d->at(x).name;
//both are pointers.
s->at(counter).roleName = d->at(x).roleValues[y].roleName;
//cout << d->at(x).roleValues[y].percent << endl;
s->at(counter).percent = &d->at(x).roleValues[y].percent;
counter++;
}
};
};
void printSuperStruct(vector <superStruct> *s)
{
for (int x = 0; x < s->size(); x++)
{
cout << "Count: " << x << endl;
cout << "Name: " << *s->at(x).name << endl;
cout << "Percent: " << *s->at(x).percent << endl;
cout << "pPercent: " << *s->at(x).pPercent << endl;
cout << "Role Name: " << *s->at(x).roleName << endl;
}
};
void sortSuperStruct(vector <superStruct> *s)
{
//runs through list
for (int i = 0; i < s->size(); i++)
{
//checks against lower element
//cout << *s->at(i).pPercent << endl;
for (int j = 1; j < (s->size()-i); j++)
{
//using pointer dereferences messed this up, but, not using them doesn't sort right
if (*s->at(j-1).pPercent < *s->at(j).pPercent)
{
//cout << *s->at(j-1).pPercent << "vs. " << *s->at(j).pPercent << endl;
//I don't think swap is working here
//superStruct temp;
//temp = s->at(j-1);
//s->at(j-1) = s->at(j);
//s->at(j) = temp;
swap(s->at(j-1), s->at(j));
//cout << *s->at(j-1).pPercent << "vs. " << *s->at(j).pPercent << endl;
}
}
}
}
int main()
{
srand (time(NULL));
int numberOfDwarves;
int numberOfRoles;
int maxLabors;
vector <superStruct> allRoles;
vector <Dwarf> myDwarves;
vector <roles> myRoles;
cout << "number of Dwarf's: " << endl;
cin >> numberOfDwarves;
cout << "max labor per dwarf" << endl;
cin >> maxLabors;
cout << "number of Roles: " << endl;
cin >> numberOfRoles;
//this will probably have to be a vector
//Dwarf myDwarfs[numberOfDwarves];
myDwarves.resize(numberOfDwarves);
allRoles.resize(numberOfDwarves*numberOfRoles);
myRoles.resize(numberOfRoles);
//init roles first
for (int x = 0; x < numberOfRoles; x++)
{
myRoles[x].name = x;
myRoles[x].setRolePriorities();
myRoles[x].setNumberToAssign(numberOfDwarves);
}
for (int x = 0; x < numberOfDwarves; x++)
{
myDwarves[x].setRoleValues(numberOfRoles, &myRoles);
myDwarves[x].name = x;
//messy having this here.
myDwarves[x].maxLabor = &maxLabors;
}
initializeSuperStruct(&allRoles, &myDwarves, numberOfRoles);
cout << "Before sort, weighted matrix" << endl;
system("pause");
printSuperStruct(&allRoles);
sortSuperStruct(&allRoles);
system("pause");
cout << "After sort, weighted matrix" << endl;
printSuperStruct(&allRoles);
}
output:
Role Name: 5
Count: 96
Name: 6
Percent: 0.175787
pPercent: 0.0178163
Role Name: 5
Count: 97
Name: 7
Percent: 0.175787
pPercent: 0.0178163
Role Name: 5
Count: 98
Name: 8
Percent: 0.175787
pPercent: 0.0178163
Role Name: 5
Count: 99
Name: 9
Percent: 0.175787
pPercent: 0.0178163
Role Name: 5

srand (time(NULL));
Call that once, at the start of main. Having that in various methods means you'll get a lot of duplicate values.
if (s->at(j-1).pPercent < s->at(j).pPercent)
That indeed compares pointer values, since the pointers don't necessarily point into the same array, with undefined behaviour (will probably compare virtual addresses). If you want to sort by value, you need to dereference
if (*s->at(j-1).pPercent < *s->at(j).pPercent)
And in
for (int j = 1; j < (s->size()-1); j++)
{
//using pointer dereferences messed this up, but, not using them doesn't sort right
if (s->at(j-1).pPercent < s->at(j).pPercent)
you never consider the last element, that should be
for(unsigned int j = 1; j < s->size() - i; ++j)
for a proper bubble sort.

Your bubble sort doesn't seem right to me.
It should resemble this:
void sortSuperStruct(vector <superStruct>& s)
for(int i = 0; i < s.size()-1; i++){
for(int j = i; j < s.size(); j++){
if(*(s[i].pPercent) < *(s[j].pPercent)){
swap(s.at(i),s.at(j));
}
}
}
}
Key differences:
i goes from 0 to size-1, not 0 to size
j goes from i to size, not 1 to size-1
the if statement tests i and j, not j and j-1
the swap also swaps i and j, not j and j-1
Minor differences:
the vector is passed by reference instead of as a pointer. This probably doesn't really matter, but it looks cleaner to me at least.
Note that this will sort from largest to smallest. If you want it smallest to largest, your if statement should have a > sign instead.

Related

Swapping two initialized arrays in C++ using Void and Pointers

I need to write a C++ program where it swaps between two 1-dimensional
arrays using pointers and functions. Firstly, a void function named showValues to display both arrays before swapping takes and also a void function named swap to swap the elements between both arrays.
My question is: I'm supposed to swap the function but for some reason it wont run and I am not sure where is the error in my code
#include <iostream>
#include <iomanip>
using namespace std;
const int SIZE = 5;
void showValues(int[],int[]);
void swap(int[],int[]);
int main() {
int array1[SIZE] = {10,20,30,40,50};
int array2[SIZE] = {60,70,80,90,100};
showValues (array1, array2);
swap(array1, array2);
return 0;
}
void showValues(int array1[], int array2[]){
cout<<"The original arrays are as shown below: " << endl;
cout << " Array 1 is: ";
for (int i = 0; i < 5; ++i) {
cout << array1[i] << " ";
}
cout << "\n Array 2 is: ";
for (int i = 0; i < 5; ++i) {
cout << array2[i] << " ";
}
}
void swap(int array1[], int array2[])
{
int temp,i;
for(i=0; i<5; ++i)
{
temp = array1[SIZE];
array1[SIZE] = array2[SIZE];
array2[SIZE] = temp;
}
cout << "\nThe swapped arrays are as shown below: " << endl;
cout << " Array 1 is: ";
for (int i = 0; i < 5; ++i) {
cout << array1[i] << " ";
}
cout << "\n Array 2 is: ";
for (int i = 0; i < 5; ++i) {
cout << array2[i] << " ";
}
}
This part of your code doesn't make sense:
temp = array1[SIZE];
array1[SIZE] = array2[SIZE];
array2[SIZE] = temp;
SIZE is 5. So, you are accessing array1[5] and array2[5], i.e. the 6th element of the array. Yet, your arrays have only 5 elements to begin with (array1[0] to array1[4], same for array2), so you are accessing elements beyond the end of the array, which is undefined behavior that is probably just corrupting memory somewhere!
You probably meant to use i here, not SIZE, then the code makes sense. Instead, it would be useful to replace the "magic number" 5 with SIZE:
for(i = 0; i < SIZE; ++i)
{
temp = array1[i];
array1[i] = array2[i];
array2[i] = temp;
}
The void swap(int array1[], int array2[]) function is where you are having trouble. You actually don't even need to have another function for the swapping. You could just use std::swap() which is defined in the #include <utility> header. Since both arrays have the same size.
For example you could do something along these lines:
#include <iostream>
#include <iomanip>
#include <utility>
const int SIZE = 5;
void showValues(int[], int[]);
void swap(int[], int[]);
int main() {
int array1[SIZE] = { 10,20,30,40,50 };
int array2[SIZE] = { 60,70,80,90,100 };
int n = sizeof(array1) / sizeof(array2[0]);
showValues(array1, array2);
std::swap(array1, array2);
std::cout << "\n\nThe swapped arrays are as shown below:\n ";
std::cout << "\nArray 1 is: ";
for (int i = 0; i < n; i++)
std::cout << array1[i] << ", ";
std::cout << "\nArray 2 is: ";
for (int i = 0; i < n; i++)
std::cout << array2[i] << ", ";
return 0;
}
void showValues(int array1[], int array2[]) {
std::cout << "The original arrays are as shown below: " << std::endl;
std::cout << "\nArray 1 is: ";
for (int i = 0; i < 5; ++i) {
std::cout << array1[i] << " ";
}
std::cout << "\nArray 2 is: ";
for (int i = 0; i < 5; ++i) {
std::cout << array2[i] << " ";
}
}
Also consider not using using namespace std;.

using functions to write the code in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Hi i'm trying to Write a program in C++ to, generate and print 20 random numbers, between 0 to 999, and do the following operations without using inbuilt functions, find and print the: min value, max value, average, median, standard deviation, variance. Do a binary search on the 15th element. Please help me with the code.
So far i've done this much
#include
#include
#include
using namespace std;
void minimum(int[], int);
void maximum (int[], int);
void average(int[], int);
void median(int[], int);
void mean(int[], int);
void sort(int[], int);
int ra()
{
int r = rand() % 1000;
return r;
}
int main ()
{
srand(time(NULL));
ra();
int array[20];
int num=20;
for (unsigned int i = 0; i < num; i++)
{
array[i] = ra();
cout << "Index: " << i << ", random number: " << array[i] << endl;
}
minimum();
new_array[20];
num=20;
for (unsigned int i = 0; i < num; i++)
{
new_array[i] = new_array();
cout << "Index: " << i << ", random number: " << minimum << endl;
}
return 0;
}
void minimum(int new_array[], int num)
{
for (unsigned int i = 0; i < num; i++)
if (new_array[i] minimum)
minimum = new_array[i];
cout << "Maximum value: " << minimum << endl;
}
void maximum (int new_array[], int num)
{
for (unsigned int i = 0; i < num; i++)
if (new_array[i] > maximum)
maximum = new_array[i];
cout << "Maximum value: " << maximum << endl;
return 0;
}
void median(int new_array[], int num)
{
//CALCULATE THE MEDIAN (middle number)
if(num % 2 != 0){// is the # of elements odd?
int temp = ((num+1)/2)-1;
cout << "The median is " << new_array[temp] << endl;
}
else{// then it's even! :)
cout << "The median is "<< new_array[(num/2)-1]<<new_array[num/2]< endl;
}
mean(new_array, num);
}
void sort(int new_array[], int num)
{
//ARRANGE VALUES
for(int x=0; x<num; x++){
for(int y=0; y<num-1; y++){
if(new_array[y]>new_array[y+1]){
int temp = new_array[y+1];
new_array[y+1] = new_array[y];
new_array[y] = temp;
}
}
}
cout << "List: ";
for(int i =0; i<num; i++){
cout << new_array[i] << " ";
}
cout << "\n";
median(new_array, num);
}
void average_(int new_array[], int nums)
{
float sum;
for (unsigned int i = 0; i < 20; ++i)
{
sum+=num;
}
cout << "Average value: " << average_/num << endl;
}
Please tell the necessary corrections
You have a ways to go, your code does not do any of the things you want yet. However, you mentioned that you are a beginner so I fixed your code and set up a basic structure of how to get going. I left comments on what I changed and what you need to do. That being said, I don't know what you mean by "Do a binary search on the 15th element"
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
int ra()
{
// You wanted a number between 0 and 999 inclusive so do not add 1
// Instead do a modulus of 1000
int r = rand() % 1000;
return r;
}
int main ()
{
// Do this to get different random numbers each time you run your program
srand(time(NULL));
// You have to call ra as a function. Do this by writing: ra()
// Here I am storing 20 random numbers in an array
int nums[20];
for (unsigned int i = 0; i < 20; ++i)
{
nums[i] = ra();
cout << "Index: " << i << ", random number: " << nums[i] << endl;
}
// Iterate to find the minimum number
int minimum = nums[0];
for (unsigned int i = 1; i < 20; ++i)
if (nums[i] < minimum)
minimum = nums[i];
cout << "Minimum value: " << minimum << endl;
// TODO: Find the maximum in basically the same way
// TODO: Find the average by summing all numbers then dividing by 20
// TODO: Find the median by sorting nums and taking the average of the two center elements
// TODO: etc.
return 0;
}
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int r;
int ra;
int i=0;
int ra(){
r = (rand() % 999) + 1;
return r;
}
int main ()
{
int random_;
srand((int)time(0));
while (i++ < 20)
{
random_ = r;
cout<< random_<<endl;
}
return 0;
}

Insertion sort implementation in C++ results in multiple errors

This is a console application on CodeBlocks 13.12.
I am getting a variety of errors when I run this Insertion Sort.
Sometimes it prints outrageously large values that weren't in the original array. Or sometimes it runs and sorts the array perfectly fine.
Can anybody please point out what could possibly be wrong? Sorry I'm a noob.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
void insertionSort(int arr[], int size);
int main()
{
int size;
srand(time(NULL));
cout << "Specify the size of your array: ";
cin >> size;
int theArray[size]; // creates an array of a size the user chooses
cout << endl << "Your current array: {";
for (int i = 0; i < size; i++) //prints out the original array
{
theArray[i] = rand() % 10000;
cout << theArray[i];
if (i != size - 1) // to beautify output
{
cout << ", ";
}
if (i % 10 == 0 && i != 0)
{
cout << endl;
}
}
cout << "}" << endl << endl;
insertionSort(theArray, size);
}
void insertionSort(int arr[], int size)
{
int begin = clock(); // are for timing the sort
for (int i = 0; i < size; i++) //does the sorting
{
int j = i + 1;
int temp = arr[j];
while (arr[i] > arr[j])
{
arr[j] = arr[i];
arr[i] = temp;
j--;
i--;
}
}
int end = clock(); // are for timing the sort
cout << endl << "Your sorted array is: {";
for (int i = 0; i < size; i++) // prints out sorted array
{
cout << arr[i];
if (i != size - 1)
{
cout << ", ";
}
if (i % 10 == 0 && i != 0)
{
cout << endl;
}
}
cout << "}" << endl << endl << "Your sort took: " << end - begin << " milliseconds" << endl << endl;
}
Additionally to #marom's answer, in your while loop, you don't put limitations neither on i or j, hence you try to access arr[-1], arr[-2] and so on. Also, you go back to the beginning of the sorted array, since you decrement i. Have a look at this code, compiled with g++ 4.8.1 gives no errors. Also, try to use std::swap defined in header <utility> since c++11 or in header <algorithm> until c++11.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <utility>
using namespace std;
void insertionSort(int arr[], int size);
int main()
{
int size;
srand(time(NULL));
cout << "Specify the size of your array: ";
cin >> size;
int theArray[size]; // creates an array of a size the user chooses
cout << endl << "Your current array: {";
for (int i = 0; i < size; i++) //prints out the original array
{
theArray[i] = rand() % 10000;
cout << theArray[i];
if (i != size - 1) // to beautify output
{
cout << ", ";
}
if (i % 10 == 0 && i != 0)
{
cout << endl;
}
}
cout << "}" << endl << endl;
insertionSort(theArray, size);
}
void insertionSort(int arr[], int size)
{
int begin = clock(); // are for timing the sort
for (int i = 0; i < size - 1; i++) //does the sorting
{
int j = i + 1;
int temp = arr[j];
while (j > 0 && arr[j] < arr[j - 1])
{
// ^^ this ensures that we don't try to access arr[-1]
swap(arr[j], arr[j-1]); //prefer std functions if they do the job you want
j--;//we don't go back
}
}
int end = clock(); // are for timing the sort
cout << endl << "Your sorted array is: {";
for (int i = 0; i < size; i++) // prints out sorted array
{
cout << arr[i];
if (i != size - 1)
{
cout << ", ";
}
if (i % 10 == 0 && i != 0)
{
cout << endl;
}
}
cout << "}" << endl << endl << "Your sort took: " << end - begin << " milliseconds" << endl << endl;
}
At least this is wrong:
void insertionSort(int arr[], int size)
{
int begin = clock(); // are for timing the sort
for (int i = 0; i < size; i++) //does the sorting
{
int j = i + 1;
When i is size-1 then j equals size and you get over the bounds of the array (valid values are from 0 to size-1 included). You need to limit your for loop to i < size-1
First advice : don't do all your printing or clock measure in your sort function. Keep that for your main program. Your sort function must remain clear and concise with no side effect.
Now, i find it better to split the code into 2 simple functions :
First, if arr is assumed already sorted up the index n-1
you want to insert the adequate element of the table at pos offset so that
arr will be sorted up to index n:
void insert(int arr[], int n){
int i=n, temp=arr[n];
while ( (arr[i-1]>temp) && (i>0) )
{
arr[i]=arr[i-1];
i--;
}
arr[i]=temp;
}
Now we just have to call our insertion for all offsets in arr except first one:
void insertionSort(int arr[], int size)
{
for(int n=1; n<size; n++) insert(arr,n);
}
As already mentioned by marom in his answer, when i = size - 1 you set j = size and access memory out of bounds, similarly, consider the case where j is set to the smallest element in the array, in that case you reach the left most position of the array by swapping the elements and decrementing, and eventually, i will become negative (since you do not put a bound to check if i becomes less than 0) and so will j and you will be accessing memory out of your bounds again.
Moreover, you are decrementing the value of i as well, which does not make sense, since by decrementing the value of i you are making extra runs for the external for loop.
So, your function shall look something like this ::
for (int i = 0; i < size - 1; i++) //changed the limit of for loop
{
int j = i + 1;
int temp = arr[j];
while ((j > 0) && (arr[j - 1] > arr[j])) //instead of working with the values of i, now we are doing everything with j
{
arr[j] = arr[j - 1];
arr[j - 1] = temp;
j--;
}
}
Hope this helps!

c++ sort: ranking list with same value of an array

I'm trying to show a ranking list of my array qt, which contains 5 numbers.
int i, j;
int qt[5] = {10,20,10,50,20};
int tempqt;
for (i=0; i<5; i++)
{
for(j=(i+1); j<5; j++)
{
if (qt[i] >= qt[j])
{
tempqt = qt[i];
qt[i] = qt[j];
qt[j] = tempqt;
}
}
}
for(i=0; i<5; i++)
{
cout << i+1 << ".number: " << qt[i] << endl;
}
normally, the 2 for-loops sort my array and the last for-loop displays my array ordered, so it looks like this:
1.number: 10
2.number: 10
3.number: 20
4.number: 20
5.number: 50
But I want to display the numbers with the same value as the same ranking position, so like this:
1.number: 10
1.number: 10
2.number: 20
2.number: 20
3.number: 50
The idea is to increase rank counter when meet different value in qt array.
i = 0;
int rank = 1, val = qt[i];
cout << rank << ".number: " << qt[i] << endl;
for(i=1; i<5; i++)
{
if (qt[i] != val) {
++rank;
val = qt[i];
}
cout << rank << ".number: " << qt[i] << endl;
}
Use std::sort to sort the array -- you won't get anywhere until the array is sorted.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int qt[5] = { 10, 20, 10, 50, 20 };
sort(qt, qt + 5);
int count = 1;
for (int i = 0; i < 5; ++i)
{
if (i > 0)
{
if (qt[i] != qt[i - 1])
++count;
}
cout << count << ".number: " << qt[i] << endl;
}
}
Here is another solution using a map. This is more "lazy" in that there is no real "check if number already seen" logic involved. Just add numbers to a map, and print out the results in a loop.
If there are no memory constraints (you will need to create a map of the numbers, of course), and/or you need the array to remain stable (not sorted), then this could be an alternative.
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int qt[5] = { 10, 20, 10, 50, 20 };
std::map<int, int> IntMap;
// add entries to map, adding to a counter each time
for (int i = 0; i < 5; ++i)
IntMap[qt[i]]++;
// output the results.
int count = 1;
for (auto it = IntMap.begin(); it != IntMap.end(); ++it, ++count)
{
for (int i = 0; i < it->second; ++i)
cout << count << ".number: " << it->first << endl;
}
}
The map already sorts, so that's taken care of. Then the map is set up to count the number of times each number shows up, so that's taken care of. The only thing left is to write a loop that just goes through the map and prints the information.
See it here: http://ideone.com/q08SeX
I'd rather use a do while loop:
int p = 1, x = 0;
do
{
cout << p << ".number: " << qt[x++] << endl;
if (x < 5 && qt[x] != qt[x-1])
p++;
} while (x < 5);

c++ can't get selection sort to work properly

I am trying to understand sorting algorithms, so based on googled examples/explanations I wrote the below code. Code works 80% of the time. Every once in a while it doesn't sort properly and I can not see why.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
void setArray( int *, const int & );
void selectionSorting( int *, const int & );
int main()
{
int numOfElem;
cout << "Num of array elements: ";
cin >> numOfElem;
cout << '\n';
int array[numOfElem];
setArray(array, numOfElem);
selectionSorting(array, numOfElem);
cout << '\n';
return 0;
}
void setArray( int *array, const int & numOfElem ){
srand(time(0));
cout << "Original array: " << '\n';
for (int i=0; i<numOfElem; i++){
array[i] = rand()%30;
cout << array[i] << ' ';
}
cout << '\n';
}
void selectionSorting( int *array, const int &numOfElem ){
int eff_size, swap;
int maxpos = 0;
for (eff_size = numOfElem; eff_size>1; eff_size--){
// loop searching for a position of largest number in the array
for (int i=0; i<eff_size; i++){
maxpos = array[i] > array[maxpos] ? i : maxpos;
}
swap = array[maxpos];
array[maxpos] = array[eff_size-1];
array[eff_size-1] = swap;
}
cout << "Selection Sorting: " << '\n';
for (int i=0; i<numOfElem; i++){
cout << array[i] << ' ';
}
}
Example output:
Num of array elements: 5
Original array:
7 17 1 12 25
Selection Sorting:
1 7 17 25 12
I can't see any pattern to the sorting failing - it fails in different places, weather there are repeated numbers, regardless of how many numbers I provide etc...
On each iteration of the outer loop(over eff_size) you should re-set maxpos to 0. Otherwise you have the chance that maxpos goes out of the effective portion being sorted(this happens if the maximum element is last in the effective portion i.e. if maxpos==effsize).