Results 1 to 8 of 8

Thread: Some quicksort help needed

  1. #1
    Join Date
    Oct 2007
    Beans
    37

    Some quicksort help needed

    Hello,
    I am trying to write a quick sort program in c++ because I am studying sorting algorithms. Below is the code I have managed to come up with so far, but when I run it the final outputted array seems to be just randomly re-arranged with no pattern that I can tell. I have stared at this for hours now and I am stuck. Any suggestions? Thanks.

    Code:
    #include<iostream>
    #include<cstdlib>
    using namespace std;
    
    //Defines
    #define ArraySize 250
    #define RandomCap 1000
    
    //Globals
    int numbers[ArraySize];
    int numbersRaw[ArraySize];
    
    //Prototypes
    void arrayPopulate();
    void arrayOutput();
    void quickSort(int startPosition, int endPosition);
    void swap(int& a, int& b);
    int splitArray(int pivot, int startPosition, int endPosition);
    
    int main(){
        //Generate arrays  
        arrayPopulate();
        
        //Sort one of the arrays
        quickSort(0,ArraySize-1);
        
        //Print array
        arrayOutput();
        
        //Wait for return
        system("PAUSE");
        return 0;   
    }
    
    void swap(int& a, int& b){
    	int temp;
    	temp = a;
    	a = b;
    	b = temp;
    }
    
    void quickSort(int startPosition, int endPosition){
    	//Assign the pivot point to the far left element
    	int pivotPoint = numbers[startPosition];
    	int splitPoint;
    	
    	//Make sure there is at least one element
    	if (endPosition>startPosition){
    		splitPoint = splitArray(pivotPoint,startPosition,endPosition);
    		
    		numbers[splitPoint] = pivotPoint;
    		quickSort(startPosition,splitPoint-1); //Quick sort the first part
    		quickSort(splitPoint+1,endPosition); //Quick sort the second part
    	}
    }
    
    int splitArray(int pivot, int startPosition, int endPosition){
    	int leftSide = startPosition;
    	int rightSide = endPosition;
    	
    	while (leftSide < rightSide){
    		while (pivot < numbers[rightSide] && rightSide > leftSide){ //Keep moving  until a smaller number is reached, or until we hit the end
    			rightSide--;
    		}
    		swap(numbers[leftSide],numbers[rightSide]); //Swap so that the pivot is to the right of the small one.
    		while (pivot >= numbers[rightSide] && leftSide < rightSide){ //Keep moving until a larger number is reached, or until we hit the end
    			leftSide++;
    		}
    		swap(numbers[leftSide],numbers[rightSide]);
    	}
    	return leftSide;
    }
    
    void arrayPopulate()
    {
    	int generateCount;
    	generateCount = 0;
    	int tempRand;
    	
    	while(generateCount<=ArraySize-1){
    		tempRand = (rand() % RandomCap) + 1;
    		numbers[generateCount]=tempRand;
    		numbersRaw[generateCount]=tempRand;
    		generateCount++;
    	}
    }
    
    void arrayOutput()
    {
        int outputCount;
        outputCount = 0;
        
        while(outputCount<=ArraySize-1){
            cout<<outputCount<<":\t"<<numbersRaw[outputCount]<<"\t"<<numbers[outputCount]<<endl;
            outputCount++;                        
        }    
    }

  2. #2
    Join Date
    Jun 2007
    Location
    Maryland, US
    Beans
    6,288
    Distro
    Kubuntu

    Re: Some quicksort help needed

    I forgot where I found this implementation, but maybe it will help you:
    PHP Code:
    const int SMALL_ENOUGH 15;


    template <typename T>
    void selectionsort(T& array, const int left, const int right)
    {
      for (
    int i leftright; ++i)
      {
        
    int min i;

        for (
    int j i+1<= right; ++j)
        {
          if (array[
    j] < array[min])
            
    min j;
        }
        
    typename T::value_type temp = array[min];
        array[
    min] = array[i];
        array[
    i] = temp;
      }
    }

    template <typename T>
    int partition(T& array, const int left, const int right)
    {
      
    typename T::value_type val = array[left];
      
    int                    lm  left-1;
      
    int                    rm  right+1;

      for(;;)
      {
        do
        {
          
    rm--;
        } while (array[
    rm] > val);

        do
        {
          
    lm++;
        } while(array[
    lm] < val);

        if (
    lm rm)
        {
          
    typename T::value_type temp = array[rm];
          array[
    rm] = array[lm];
          array[
    lm] = temp;
        }
        else
        {
          return 
    rm;
        }
      }
    }

    template <typename T>
    void quicksort(T& array, const int left, const int right)
    {
      if (
    left < (right SMALL_ENOUGH))
      {
        
    int split partition(array, leftright);
        
    quicksort(array, leftsplit);
        
    quicksort(array, split+1right);
      }
      else
      {
        
    selectionsort(array, leftright);
      }

    Btw, why are you using global variables? Why not just declare your arrays in your main() function, then pass them to the appropriate function(s) to have manipulated.

  3. #3
    Join Date
    Oct 2005
    Location
    Queensland, Australia
    Beans
    Hidden!
    Distro
    Ubuntu Development Release

    Re: Some quicksort help needed

    At a very quick glance, I noticed
    quickSort(startPosition,splitPoint-1); //Quick sort the first part
    quickSort(splitPoint+1,endPosition); //Quick sort the second part
    splitPoint-1 and splitPoint+1, what about the one between them?
    Not sure if that is causing your problem though.
    Cheers, Mike

  4. #4
    Join Date
    Oct 2007
    Beans
    37

    Re: Some quicksort help needed

    The one between them is already in its proper place, that is the pivot from the last iteration and doesn't need to be sorted again.

    I tried constraining the number of items to 1 to better see whats going on and this is what I got:
    0: 42 42
    1: 468 170
    2: 335 335
    3: 501 501
    4: 170 359
    5: 725 479
    6: 479 725
    7: 359 465
    8: 963 963
    9: 465 468
    It looks like it manages to get the first few steps right at least, then it just breaks down. I'm so confused.

  5. #5
    Join Date
    Oct 2005
    Location
    Queensland, Australia
    Beans
    Hidden!
    Distro
    Ubuntu Development Release

    Re: Some quicksort help needed

    jjb123, I think I found your error now that I've has more than 10 secs to look at your prog. See below.
    Should be leftSide not rightSide.

    while (pivot >= numbers[leftSide/*rightSide*/] && leftSide < rightSide)
    { //Keep moving until a larger number is reached, or until we hit the end
    leftSide++;
    }

  6. #6
    Join Date
    Oct 2007
    Beans
    37

    Re: Some quicksort help needed

    Wow, thanks that did the trick. It's always something simple Thanks again!

  7. #7
    Join Date
    Feb 2008
    Location
    /home/
    Beans
    379
    Distro
    Ubuntu 7.04 Feisty Fawn

    Re: Some quicksort help needed

    unless you are doing this to learn, use the C version of sort. It combines heap and quick to get the best possible, and will be faster than anything you could make (no offense, but its true).

    But if you are doing it to learn then thats just fine, but for any application, use C's
    If there's one thing worse than a program that doesn't work when it should, it's a program that does work when it shouldn't.

    Bob Archer

  8. #8
    Join Date
    Oct 2007
    Beans
    37

    Re: Some quicksort help needed

    Interesting, what is the name of it? Just C sort?

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •