我是计算机科学专业的新生,在使用指针时仍然遇到一些困难。我正在尝试用C实现一个快速排序程序。我目前有2个错误,但我不知道如何解决它。
在主函数上,当我调用分区时,得到了不兼容的指针类型
在交换功能上:线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x200000007)
v1.2.3
答案 0 :(得分:1)
对于初学者,如果数组具有N个元素,则索引的有效范围为[0, N-1]
因此,尝试访问阵列之外的内存
int pivot = size;
int i = - 1;
for(int j = 0 ; j < size - 1 ; j++){
if(array[j] < array[pivot])
^^^^^^^
您的函数交换没有意义。
void swap(int *i, int* j){
*i = *j;
*j = *i;
*i = *j;
}
在第一个表达式语句之后
*i = *j;
指针i
和j
所指向的两个对象都将具有相同的值。
可以通过以下方式定义函数。
void swap( int *p, int *q )
{
int tmp = *p;
*p = *q;
*q = tmp;
}
并称呼为
swap( &array[i], &array[j] );
功能分区也无效。除了错误使用的算法外,至少它的第一个参数也被错误地声明。
代替
void partition( int* array[], int size );
函数应声明为
void partition( int *array, int size );
或更正确地
void partition( int *array, size_t size );
,该函数应类似于
int array[] = {7,2,1,8,6,3,5,4};
size_t size = sizeof(array)/sizeof(array[0]);
partition( array,size );
另一方面,函数partition
应该返回将数组分为两部分的位置。所以最终的函数声明看起来像
size_t partition( int array[], size_t size );
下面有一个演示程序,显示了如何使用函数swap
和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;
}
程序输出为
7 2 1 8 6 3 5 4
1 2 3 4 5 6 7 8
答案 1 :(得分:0)
这里有一些问题:
int* array[]
是一个指向整数的指针数组,而您在main中使用的指针是指向整数数组。array[j] < array[pivot]
应该是内容的比较,而int* array[]
是地址的比较),因此您应该将其更改为是int array[]
。请注意,这也将有助于解决第1点,因为在调用partition时只需要删除多余的引用即可。swap(array[i],array[j])
(假设您已进行上述建议的更正)时,您传递的是int
,而不是int*
,则需要将其更改为swap(&array[i],&array[j])
。void swap(int *i, int* j){
int temp = *j;
*j = *i;
*i = temp;
}
使用排他性或的版本
void swap(int *i, int* j){
*i= *j ^ *i;
*j= *j ^ *i;
*i= *j ^ *i;
}
答案 2 :(得分:0)
指针
我不确定问题是否在问基于指针的快速排序,所以这是一个使用Lomuto分区方案的示例。在分区循环中,它在较小的部分上递归,然后在较大的部分上循环,将堆栈空间限制为O(log(n)),但最坏的情况下时间复杂度仍为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;
}
}
}