I am a computer science freshman and I still have some difficulties when it comes to pointers. I am trying to implement a quick sort program in CI currently have 2 errors but I am not able to figure out how to fix it.
On the main function, when I am calling partition, I got an Incompatible pointer types
On the swap function: Thread 1: EXC_BAD_ACCESS (code=1, address=0x200000007)
void swap(int *i, int* j){
*i = *j;
*j = *i;
*i = *j;
}
void partition(int* array[], int size){
int pivot = size;
int i = - 1;
for(int j = 0 ; j < size - 1 ; j++){
if(array[j] < array[pivot]){
i++;
swap(array[i],array[j]);
}
}
}
int main() {
int array[] = {7,2,1,8,6,3,5,4};
int size = sizeof(array)/sizeof(array[0]);
partition(&array,size);
return 0;
}
For starters if an array has N elements then the valid range of indices is [0, N-1]
Thus there is an attempt to access memory beyond the array
int pivot = size;
int i = - 1;
for(int j = 0 ; j < size - 1 ; j++){
if(array[j] < array[pivot])
^^^^^^^
Your function swap does not make sense.
void swap(int *i, int* j){
*i = *j;
*j = *i;
*i = *j;
}
After the first expression statement
*i = *j;
the both objects pointed to by the pointers i
and j
will have the same value.
The function can be defined the following way.
void swap( int *p, int *q )
{
int tmp = *p;
*p = *q;
*q = tmp;
}
and called like
swap( &array[i], &array[j] );
The function partition is also invalid. Apart from the incorrect used algorithm at least its first parameter is declared also incorrectly.
Instead of
void partition( int* array[], int size );
the function should be declared like
void partition( int *array, int size );
or more correctly like
void partition( int *array, size_t size );
and the function should be called like
int array[] = {7,2,1,8,6,3,5,4};
size_t size = sizeof(array)/sizeof(array[0]);
partition( array,size );
On the other hand, the function partition
should return the position that divides the array into two parts. So the final function declaration will look like
size_t partition( int array[], size_t size );
Below there is a demonstrative program that shows how a recursive function quick sort can be written using functions swap
and partition
.
#include <stdio.h>
void swap( int *p, int *q )
{
int tmp = *p;
*p = *q;
*q = tmp;
}
size_t partition( int a[], size_t n, int pivot )
{
size_t i = 0;
while ( i != n )
{
while ( i != n && a[i] < pivot ) i++;
while ( i != n && !( a[--n] < pivot ) );
if ( i != n ) swap( a + i, a + n );
}
return i;
}
void quick_sort( int a[], size_t n )
{
if ( n != 0 )
{
size_t pos = partition( a, n - 1, a[n - 1] );
swap( a + pos, a + n - 1 );
quick_sort( a, pos );
quick_sort( a + pos + 1, n - pos - 1 );
}
}
int main(void)
{
int a[] = { 7, 2, 1, 8, 6, 3, 5, 4 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
quick_sort( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output is
7 2 1 8 6 3 5 4
1 2 3 4 5 6 7 8
There are a few problems in here:
int* array[]
in partition is an array of pointers to integers, while what you call it with in main is a pointer to an array of integers.array[j] < array[pivot]
should be a comparison of content, but with an int* array[]
it is a comparison of address), so you should change it to just being an int array[]
. Note that this will also help with resolving point 1, as you just need to remove the superflous referencing when you call partition.swap(array[i],array[j])
(assuming you have made the corrections suggested above) you are passing int
s and not int*
s, you need to change it to swap(&array[i],&array[j])
.void swap(int *i, int* j){
int temp = *j;
*j = *i;
*i = temp;
}
An a version using exlusive or:
void swap(int *i, int* j){
*i= *j ^ *i;
*j= *j ^ *i;
*i= *j ^ *i;
}
pointers
I wasn't sure if the question was asking about a pointer based quicksort, so here is an example, using Lomuto partition scheme. In the partition loop, it recurses on the smaller part, and loops back for the larger part, limiting stack space to O(log(n)), but worst case time complexity remains at O(n^2).
void QuickSort(int *lo, int *hi)
{
int *pi;
int *pj;
int pv;
int t;
while (lo < hi){
pv = *hi; /* pivot */
pi = lo; /* partition */
for (pj = lo; pj < hi; ++pj){
if (*pj < pv){
t = *pi; /* swap *pi, *pj */
*pi = *pj;
*pj = t;
++pi;
}
}
t = *pi; /* swap *pi, *hi */
*pi = *hi; /* to place pivot */
*hi = t;
if(pi - lo <= hi - pi){ /* recurse on smaller part */
QuickSort(lo, pi-1); /* loop on larger part */
lo = pi+1;
} else {
QuickSort(pi+1, hi);
hi = pi-1;
}
}
}
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.