C 使用快速排序获取数组的已排序索引

C 使用快速排序获取数组的已排序索引,c,quicksort,C,Quicksort,我已改为使用快速排序代码对从tutorialgateway.org获得的浮点数组进行排序。然而,我需要排序索引。我知道qsort库函数可用于获取排序索引,我可以实现它。但是,我想避免使用标准库(我知道这不是推荐的)。不使用标准库的原因是我需要在循环中对大量数组进行排序,我需要使用openMP并行化,因此显式编写函数将允许我在循环中并行化快速排序函数 /* C Program for Quick Sort */ #include <stdio.h> void Swap(float *

我已改为使用快速排序代码对从tutorialgateway.org获得的浮点数组进行排序。然而,我需要排序索引。我知道
qsort
库函数可用于获取排序索引,我可以实现它。但是,我想避免使用标准库(我知道这不是推荐的)。不使用标准库的原因是我需要在循环中对大量数组进行排序,我需要使用
openMP
并行化,因此显式编写函数将允许我在循环中并行化快速排序函数

/* C Program for Quick Sort */
#include <stdio.h>

void Swap(float *x, float *y) {
    float Temp;
    Temp = *x;
    *x = *y;
    *y = Temp;
}

void quickSort(float a[], int first, int last) {
    int i, j;
    int pivot;
    if (first < last) {
        pivot = first;
        i = first;
        j = last;
        while (i < j) {
            while (a[i] <= a[pivot] && i < last)
                i++;
            while (a[j] > a[pivot])
                j--;
            if (i < j) {
                Swap(&a[i], &a[j]);
            }
        }
        Swap(&a[pivot], &a[j]);
        quickSort(a, first, j - 1);
        quickSort(a, j + 1, last);
    }
}

int main() {
    int number, i;
    float a[100];
    printf("\n Please Enter the total Number of Elements  :  ");
    scanf("%d", &number);
    printf("\n Please Enter the Array Elements  :  ");
    for (i = 0; i < number; i++)
        scanf("%f", &a[i]);

    quickSort(a, 0, number - 1);
    printf("\n Selection Sort Result : ");
    for (i = 0; i < number; i++)  {
        printf(" %f \t", a[i]);
    }
    printf("\n");
    return 0;
}
/*用于快速排序的C程序*/
#包括
无效交换(浮动*x,浮动*y){
浮子温度;
温度=*x;
*x=*y;
*y=温度;
}
void快速排序(浮点a[],int first,int last){
int i,j;
int轴;
如果(第一次<最后一次){
枢轴=第一;
i=第一;
j=最后一个;
而(i

如何返回代码中已排序的索引

您需要生成一个从0到size-1的索引数组,然后根据数组值对索引数组进行排序。因此,代码使用数组[index[…]进行比较,并在索引[…]上进行交换

另一种方法是生成从&array[0]到&array[size-1]的指针数组。对指针进行排序后,可以使用:index[i]=pointer[i]-&array[0]将它们转换为索引(可以使用索引和指针的并集)


具有标准版Hoare分区方案的示例程序,用于根据[]中的浮点值对I[]中的索引数组进行排序:

#include <stdio.h>
#include <stdlib.h>

void QuickSort(float A[], size_t I[], size_t lo, size_t hi)
{
    if (lo < hi)
    {
        float pivot = A[I[lo + (hi - lo) / 2]];
        size_t t;
        size_t i = lo - 1;
        size_t j = hi + 1;
        while (1)
        {
            while (A[I[++i]] < pivot);
            while (A[I[--j]] > pivot);
            if (i >= j)
                break;
            t = I[i];
            I[i] = I[j];
            I[j] = t;
        }
        QuickSort(A, I, lo, j);
        QuickSort(A, I, j + 1, hi);
    }
}

#define COUNT (4*1024*1024)             // number of values to sort

int main(int argc, char**argv)
{
    int  r;                             // random number
    size_t i;

    float  * A = (float *)  malloc(COUNT*sizeof(float));
    size_t * I = (size_t *) malloc(COUNT*sizeof(size_t));

    for(i = 0; i < COUNT; i++){         // random floats
        r  = (((rand()>>4) & 0xff)<< 0);
        r += (((rand()>>4) & 0xff)<< 8);
        r += (((rand()>>4) & 0xff)<<16);
        r += (((rand()>>4) & 0xff)<<24);
        A[i] = (float)r;
    }

    for(i = 0; i < COUNT; i++)          // array of indexes
        I[i] = i;

    QuickSort(A, I, 0, COUNT-1);

    for(i = 1; i < COUNT; i++){
        if(A[I[i-1]] > A[I[i]]){
            printf("error\n");
            break;
        }
    }

    free(I);
    free(A);

    return(0);
}
#包括
#包括
无效快速排序(浮动A[],大小I[],大小低,大小高)
{
如果(低<高)
{
浮动轴=A[I[lo+(hi-lo)/2];
尺寸t;
尺寸i=lo-1;
尺寸j=hi+1;
而(1)
{
while(A[I[++I]]pivot);
如果(i>=j)
打破
t=I[I];
I[I]=I[j];
I[j]=t;
}
快速排序(A、I、lo、j);
快速排序(A、I、j+1、hi);
}
}
#定义计数(4*1024*1024)//要排序的值的数目
int main(int argc,字符**argv)
{
int r;//随机数
尺寸i;
float*A=(float*)malloc(COUNT*sizeof(float));
size_t*I=(size_t*)malloc(COUNT*sizeof(size_t));
对于(i=0;i>4)和0xff)>4)和0xff)>4)和0xff)4)和0xff)枢轴;
如果(i>=j)
打破
t=I[I];
I[I]=I[j];
I[j]=t;
}
/*避免堆栈溢出*/
如果((j-lo)<(hi-j)){
快速排序(A、I、lo、j);
lo=j+1;
}否则{
快速排序(A、I、j+1、hi);
hi=j;
}
}
}

注意,
qsort()
可能没有实现快速排序。我对创建索引数组有点困惑。如果我这样做,我将需要编写另一个交换函数,可以将整数作为参数?在这种情况下,我是否要重复索引数组的快速排序函数中的最后3行?对于同样有交换的if循环,也有类似的情况?@dipaksanap-我注意到一个问题,您希望pivot是一个值,而不是一个索引,在本例中,
float pivot=a[first+(last first)/2]。中间值无需检查
i
。您将比较(数组[index[…],pivot),但交换(index[…],index[…])。当我将pivot更改为[first+(last first)/2]时,程序将永远运行。我认为这个程序是用数组的第一个元素作为轴来编写的。@dipaksanap-应该是
pivot=a[index[first+(last first)/2],因为代码正在对索引进行排序。我用示例代码更新了我的答案,对快速排序分区逻辑做了一些细微的修改。实现得很干净。糟糕的是,当所有数组元素都具有相同的值时,它会爆炸。
void QuickSort(float A[], size_t I[], size_t lo, size_t hi)
{
    while (lo < hi)
    {
        float pivot = A[I[lo + (hi - lo) / 2]];
        size_t t;
        size_t i = lo - 1;
        size_t j = hi + 1;
        while (1)
        {
            while (A[I[++i]] < pivot);
            while (A[I[--j]] > pivot);
            if (i >= j)
                break;
            t = I[i];
            I[i] = I[j];
            I[j] = t;
        }
        /* avoid stack overflow */
        if((j - lo) < (hi - j)){
            QuickSort(A, I, lo, j);
            lo = j+1;
        } else {
            QuickSort(A, I, j + 1, hi);
            hi = j;
        }
    }
}