简体   繁体   中英

bubble sort using pointers

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM