简体   繁体   中英

Quick sort with pointers

I need to code a quick sort algorithm in C as homework. This is the prototype I was given:

static inline
int* choose_pivot(int *left, int *right) {
    /* FIX ME */
}

/*
 * partition(left, right, pivot): push value less than *pivot on the left
 * return the new pivot.
 */
 int* partition(int *left, int *right, int *pivot) {
     /* FIX ME */
 } 

 /*
 * quick_sort(left, right)
 */
 void quick_sort(int *left, int *right) {
     /* FIX ME */
 }

where left is the pointer to the first element of the array and right , the pointer to the last element (excluded). I wrote the following code:

static inline
int* choose_pivot(int *left, int *right) {
    return &left[(right - left)/2];
}

void swap(int *a, int *b) {
    int c = *a;
    *a = *b;
    *b = c;
}  

int* partition(int *left, int *right, int *pivot) {
    int *i, *q;
    q = right;
    i = left ;
    while ( q > pivot ) {
        while ( pivot < i )
            pivot++;
        while ( q > i )
            q--;
        if ( *q > *pivot ) {
           swap(pivot,q);
        }
    }
    swap(left, q);
    return q ;
}

void quick_sort(int *left, int *right) {
    if(left >= right)
        return;

    int *pivot = partition(left, right, choose_pivot(left, right));
    quick_sort(left, pivot-1);
    quick_sort(pivot + 1, right);
}

I am running 3 kind of tests: one on a sorted array, one on a reverse sorted one and, one on reverse sorted one. the first test works well, but the second and this ones fails. Basically meaning the functions doesn't work. I can't find any documentation on what I am supposed to do since all quick sort algorithm uses its length instead of a pointer on the last element and I couldn't adapt the ones I've found to my representation. What is going wrong here?

EDIT:

My new partition function now looks like this after the comments:

int* partition(int *left, int *right, int *pivot) {
    int *i, *q;
    q = right;
    i = left ;
    int p = *pivot;

    while ( q > pivot ) {
        while ( p < *i )
            pivot++;
        while ( *q > *i )
            q--;
        if ( q > pivot ) {
            swap(pivot,q);
        }
    }

    swap(left, q);
    return q ;
}

Here is the simple function of quick sort using pointers..

quicksort( void *a, int low, int high )
  {
  int pivot;
  /* Termination condition! */
  if ( high > low )
    {
    pivot = partition( a, low, high );
    quicksort( a, low, pivot-1 );
    quicksort( a, pivot+1, high );
    }
  }

Function of Partition

int partition( void *a, int low, int high )
  {
  int left, right;
  void *pivot_item;
  pivot_item = a[low];
  pivot = left = low;
  right = high;
  while ( left < right ) {
    /* Move left while item < pivot */
    while( a[left] <= pivot_item ) left++;
    /* Move right while item > pivot */
    while( a[right] > pivot_item ) right--;
    if ( left < right ) SWAP(a,left,right);
    }
  /* right is final position for the pivot */
  a[low] = a[right];
  a[right] = pivot_item;
  return right;
  }

Hope this helps!!

void quick_sort (int *a, int n) {
    if (n < 2)
        return;
    int p = a[n / 2];
    int *l = a;
    int *r = a + n - 1;
    while (l <= r) {
        if (*l < p) {
            l++;
        }
        else if (*r > p) {
            r--;
        }
        else {
            int t = *l;
            *l = *r;
            *r = t;
            l++;
            r--;
        }
    }
    quick_sort(a, r - a + 1);
    quick_sort(l, a + n - l);
}

int main () {
    int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1};
    int n = sizeof a / sizeof a[0];
    quick_sort(a, n);
    printf("%d", a[]);
    return 0;
}


//  [1]: https://www.cse.ust.hk/~dekai/271/notes/L01a/quickSort.pdf
//  [2]: http://www.cprogramming.com/tutorial/computersciencetheory/quicksort.html
 // [3]: http://rosettacode.org/wiki/Sorting_algorithms/Quicksort

There are problems with your approach:

  • pivot points to an element in the array which might change during the course of the partition function. You should swap the value pointed to by pivot with that of the first element and set pivot = left to to prevent this problem.
  • you compare the pointers instead of the values in the loops in function partition ... instead of while (pivot < i) you should write while (*pivot < *i) etc.

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