0

I have a bit of homework help if you don't mind. Basically the idea is to perform a quickselect on an array of values, however we were given a template and I can't seem to figure out how to get the functions to work with what is provided.

The problem is that the values will not arrange themselves properly, or if they do they will change every time the same value is input.

Here are the functions I'm working with, I'll denote the code that I have written with a /**/ after the code and any other line is part of the template that was provided for me.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>

using namespace std;

int partition(int *A, int len, int pivot_index)
{
   int pivot_value = A[pivot_index]; /**/

   int left = 0; /**/
   int l = left; /**/
   int right = len - 1; /**/
   while(left < right)  /**/
   { /**/
      while(A[left] < pivot_value) /**/
      { /**/
         left++; /**/
      } /**/

      while(A[right] > pivot_value) /**/
      { /**/
         right--; /**/
      } /**/

      if(A[left] < pivot_value) /**/
      { /**/
         swap(A[left], A[right]); /**/
      } /**/
  } /**/

  return left; /**/
}


int select (int *A, int len, int rank)
{
      if (len==1) return A[0];
      int pivot_index = rand() % len;
      int pivot_rank = partition(A, len, pivot_index);  

      if (rank == pivot_rank) return A[rank];
      if (rank < pivot_rank) return select(A, pivot_rank, rank);
      return select(A, len - pivot_rank, rank - pivot_rank ); /**/
}

int main(void)
{
   int N, *A;

   ifstream fin("test.txt");
   fin >> N;
   A = new int[N];
   for (int i=0; i<N; i++) fin >> A[i];
   fin.close();

   int r;
   cout << "Enter rank (0.." << N-1 << ")\n";
   while (cin >> r) {
      if (r < 0 || r >= N)
        cout << "Invalid rank\n";
     else 
        cout << "The element of rank " << r << " is " << select(A,N,r) << "\n";
   }

  delete[] A;
}

My "test.txt" file contains the following values:

10 -- this denotes the length of the array or how many values it will read in
7
14
12
2
25
18
15
13
100
63

Any help with this would be greatly appreciated.. my professor did not explain how this would work at all and any other examples I have found online do not answer my question. I have spent numerous hours fiddling with different ways of implementing this and at this point I just have no idea. Thanks

EDIT: changed so now can directly implement and compile. Also added the libraries I'm using

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • Is this a search issue or a sort issue? The fastest way to select an item from an array is to use an index variable, like `a[6]`. – Thomas Matthews Mar 09 '13 at 19:51
  • I might suggest to find a way to add markers that wouldn't require someone to change it in order to compile it - like `//**`! – ChiefTwoPencils Mar 09 '13 at 19:51
  • This is a search issue. I'm trying to return what the value, indexed at A[#], should be. For instance the values [4,9,5,7] and I want to find the value of A[2]. The array here would return '5' but it needs to return the value '7'. – user2152260 Mar 09 '13 at 20:12

1 Answers1

1

There are numerous issues with your code.

while(A[left] < pivot_value) {  left++; }

This does not check to that left does not run beyond the end of the array.

while(A[right] > pivot_value) { right--;} 

This does not check to that right does not run before the start of the array.

while(left < right) 

This an infinite loop when

  1. left < right
  2. A[left] >= pivot_value
  3. A[right] <= pivot_value

select(A, len - pivot_rank, rank - pivot_rank );

This is not the correct partition to continue with.

Thomas
  • 4,980
  • 2
  • 15
  • 30
  • The first two identified issues are not issues. The pivot by definition is an index inclusively between left and right. Therefore (A[left] < pivot_value) will be false as soon as the pivot slot is reached, including when left == pivot from the very get-go. Therefore left cannot increment beyond the pivot slot, and thus cannot walk past the end of the array. The same is true in reverse with right, and decrementing, respectively. Neither are issues. The infinite loop, however. *is* an issue, as is the partitioning. – WhozCraig Mar 09 '13 at 22:21