[英]C - Custom qsort not working
我正在尝试使具有相同参数的qsort类型的函数。 我还编写了3个函数来比较int,float和character。 由于某种原因,它在任何情况下都不起作用。 我不知道这是我的qsortx函数是否存在问题,但是我检查了几次,它应该可以正常工作。 我不确定是什么问题,还是我做错了。 我目前正在学习函数指针,但可能没有与之相关的所有东西。 提前致谢。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void qsortx(void*, int, int, int (*)(const void*, const void*));
int intcmp();
int floatcmp();
int charcmp();
int main()
{
int i,n;
char items[]={'c', 'a', 'b'};
n = 3;
for (i=0;i<n;++i) {
printf("%c ", items[i]);
}
printf("\n");
qsortx(items, n, sizeof(char), charcmp);
for (i=0;i<n;++i) {
printf("%c ", items[i]);
}
printf("\n");
return 0;
}
void qsortx (void *tp, int length, int pace, int(*fp)(const void* a, const void* b)) {
int switched,i,j;
void *p;
p=(void*)malloc(pace);
switched = 1;
while (1) {
if (switched == 0) {
return;
}
switched = 0;
for (i=0; i<length-1;++i) {
for (j=0;j<length-1;++j) {
printf("%c %c", tp+i, tp+j);
if (fp(tp+i, tp+j) > 0) {
memcpy(p, tp+i, pace);
memcpy(tp+i, tp+j, pace);
memcpy(tp+j, p, pace);
switched++;
}
}
}
}
}
int intcmp(const void* a, const void* b) {
return *(int*)a - *(int*)b;
}
int floatcmp(const void* a, const void* b) {
return *(float*)a - *(float*)b;
}
int charcmp(const void* a, const void* b) {
return *(char*)a - *(char*)b;
}
您有多个与指针算术和元素大小有关的问题。 您的排序中也有一个逻辑错误(我想您知道这是一个单向振动器排序)。 这是qsortx()
函数的版本,可解决这些缺陷:
void qsortx (void *tp, int length, int pace, int(*fp)(const void* a, const void* b)) {
if (length > 1) {
char *bound = ((char *) tp) + (length * pace);
char *p = malloc(pace);
char *item1p;
for (item1p = tp; item1p < (bound - pace); item1p += pace) {
char *item2p;
for (item2p = item1p + pace; item2p < bound; item2p += pace) {
if (fp(item1p, item2p) > 0) {
memcpy(p, item1p, pace);
memcpy(item1p, item2p, pace);
memcpy(item2p, p, pace);
}
}
}
free(p);
}
}
注意:
char *
类型的值执行的。 pace
),否则您只会打乱数据。 switched ++
相比, switched = 1
是更好的选择,因为它不会溢出,并且您关心的只是零与非零。 (更新:但是switched
不再重要。) item1p
循环导致零交换,则提早退出是不正确的。 仅仅因为一个元素已经在其正确的位置并不意味着所有后续元素也都在其正确的位置。 我更新了上面的代码以删除该行为。 free(p)
。 bound - pace
相关的不确定行为(如果length
为零)。 这是快速排序(qsort)算法的伪代码和实现,以及一些辅助代码,如http://www.codingbot.net/2013/01/quick-sort-algorithm-and-c-code中所定义。 html网页:请注意,此算法与qsort()稍有不同,因为它具有不同的参数列表和某些其他详细信息。 但是,基本算法是相同的。
function quicksort('array')
if length('array') ≤ 1
return 'array' // an array of zero or one elements is already sorted
select and remove a pivot value 'pivot' from 'array'
create empty lists 'less' and 'greater'
for each 'x' in 'array'
if 'x' ≤ 'pivot'
then append 'x' to 'less'
else
append 'x' to 'greater'
endif
end for
return concatenate(quicksort('less'), 'pivot', quicksort('greater') );
notice that qsort is a partition sort, using recursion.
#include<stdio.h>
#include<conio.h>
void quick_sort(int arr[20],int,int);
int main()
{
int arr[20],n,i;
clrscr();
printf("Enter the number of elements in the Array: ");
if( 1 != scanf(" %d",&n) )
{
perror( "scanf for count of elements" );
exit(1);
}
printf("\nEnter %d elements:\n\n",n);
for(i=0 ; i<n ; i++)
{
printf(" Array[%d] = ",i);
if( 1 != scanf(" %d",&arr[i]) )
{
perror( "scanf for element values" );
exit(2);
}
}
quick_sort(arr,0,n-1);
printf("\nThe Sorted Array is:\n\n");
for(i=0 ; i<n ; i++)
{
printf(" %4d",arr[i]);
}
getch();
}
void quick_sort(int arr[20],int low,int high)
{
int pivot; // used in partitioning the array
int j; // loop index
int temp; // for swapping
int i; // loop index
if(low<high)
{
pivot = low;
i = low;
j = high;
while(i<j)
{
// find next item not in proper sequence
while((arr[i] <= arr[pivot]) && (i<high))
{
i++;
}
// find next item not in proper sequence
while(arr[j] > arr[pivot])
{
j--;
}
// following is where a callback function would be invoked
if(i<j)
{
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
temp=arr[pivot];
arr[pivot] = arr[j];
arr[j]=temp;
// following is where recursion is used to perform sort on sub partitions
quick_sort(arr,low,j-1);
quick_sort(arr,j+1,high);
}
}
对于您的目的,这是一种更好的算法。 但是,它仅处理整数,因此您需要将比较函数作为第4个参数添加到quicksort()并修改代码以使用比较函数
#include <stdio.h>
#include <stdlib.h>
void swap(int *x,int *y);
int choose_pivot(int i,int j );
void quicksort(int list[],int m,int n);
void display(int list[],const int n);
int main()
{
const int SIZE = 10;
int list[SIZE];
int i = 0;
/* generates random numbers and fill the list */
for(i = 0; i < SIZE; i++ )
{
list[i] = rand();
}
printf("The list before sorting is:\n");
display(list,SIZE);
/* sort the list using quicksort algorithm */
quicksort(list,0,SIZE-1);
printf("The list after sorting:\n");
display(list,SIZE);
}
void swap(int *x,int *y)
{
// for integer swaps, 3 exclusive OR operations would be much faster
// and not require a temp variable
int temp;
temp = *x;
*x = *y;
*y = temp;
}
int choose_pivot(int i,int j )
{
return((i+j) /2);
}
void quicksort(int list[],int m,int n)
{
int key,i,j,k;
if( m < n)
{
k = choose_pivot(m,n);
swap(&list[m],&list[k]);
key = list[m];
i = m+1;
j = n;
while(i <= j)
{
while((i <= n) && (list[i] <= key))
{
i++;
}
while((j >= m) && (list[j] > key))
{
j--;
}
if( i < j)
{
swap(&list[i],&list[j]);
}
}
/* swap two elements */
swap(&list[m],&list[j]);
/* recursively sort the lesser list */
quicksort(list,m,j-1);
quicksort(list,j+1,n);
}
}
void display(int list[],const int n)
{
int i;
for(i=0; i<n; i++)
{
printf("%d\t",list[i]);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.