迭代快速排序使用堆栈

时间:2015-03-25 09:26:42

标签: c stack iteration quicksort

嗨,有人可以用我的代码帮助我,我不知道哪里出错了 这是使用堆栈的迭代快速排序,使用void **指针

传递数组
int partition(void **A, int n, void *pivot){
    void * temp;
    int left = 0,j = 0;
    int right = n-1;
    int i = left;
    for (j=left;j<right;j++){
        if ((long)A[j] < (long)pivot){
            i++;
            temp = A[i];
            A[i] = A[j];
            A[j] = temp;
        }
    }
    temp = A[i+1];
    A[right] = A[i+1];
    A[i+1] = temp;
    return i+1;
}
void myQuicksort(void **A, int n) {
    Stack *s = stack_new();     /*making new stack and allocating memory*/
    stack_push(s,(int*)0);      /*pushing left and then right*/
    stack_push(s,(int*)(n-1));
    while (!stack_isEmpty(s)){
        int right = (int)stack_pop(s);  /*poping return right then left*/
        int left = (int)stack_pop(s);
        if (right-left >=1){
            int pivot = (right+left)/2;  /* taking middle element as pivot */
            int p = partition(A+left , right-left+1 , A[pivot]);/*getting partition index*/
            stack_push(s, (int*)left);  
            stack_push(s, (int*)(p-1));
            stack_push(s,(int*)(p+1));
            stack_push(s,(int*)right);
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

显然,这是您要实施的快速排序算法http://en.wikipedia.org/wiki/Quicksort#Algorithm

首先在A中将两个指针交换为long的便捷函数。

void swap(long **A, int i, int j)
{
   long *temp = A[i];
   A[i] = A[j];
   A[j] = temp;
}

分区功能如下。

请注意,您的代码缺少第一次交换。如果您选择hi作为pivotIndex,则不需要它。但这不是你做的。

另请注意,您执行i(storeIndex)的预先增量,这是一个错误。你应该首先进行交换,然后增加i。我通过使用postincrement在一条指令中组合交换和增量。因此交换i + 1并返回i + 1是错误的。

int partition(long **A, int lo, int hi)
{
    int pivotIndex = (hi+lo)/2, storeIndex = lo, i;
    long pivotValue = *A[pivotIndex];

    swap(A, pivotIndex, hi);
    for (i = lo; i < hi; ++i)
        if (*A[i] < pivotValue)
            swap(A, i, storeIndex++); /* Note: post increment of storeIndex */
    swap(A, storeIndex, hi);
    return storeIndex;
}

你的功能 Je ne serai donc pas disponible mercrediprochainà11hcomme nous avions convenu。 myQuickSort然后变成如下。 请注意,您的堆栈现在必须存储int(索引)而不是int *。

void myQuicksort(void **A, int n) 
{
    int lo, hi, p;
    Stack *s = stack_new();     /* making new stack and allocating memory */
    stack_push(s, 0);      /* pushes initial lo and hi values */
    stack_push(s, n-1);    
    while (!stack_isEmpty(s))
    {
        hi = stack_pop(s);  
        lo = stack_pop(s);
        if (lo < hi)
        {
            p = partition(A, lo, hi);
            stack_push(s, lo);  
            stack_push(s, p-1);
            stack_push(s, p+1);
            stack_push(s, hi);
        }
    }
}

此代码尚未经过测试,因为我手头没有堆栈和数组。

为了使用此代码,您必须修复堆栈以便存储整数。

我更改了您的变量名称并使用hi和lo而不是您的方法,因为这样您只在堆栈中存储了整数值。它更简单,更清晰。

<强>更新

由于此处强加了partition()的签名,因此是一个新的代码提案。 此签名的问题在于您不知道枢轴在A中的存储位置。当partition()结束时,枢轴值必须存储在A [i]中。因此,在开始分区之前,我们必须找到它并将其存储在A [右侧]中。

int partition(void **A, int n, void *pivot){
    void * temp;
    int left = 0, j = 0;
    int right = n-1;
    int i = left;

    // locate the pivot
    for (j = 0; j < n; ++j)
        if (*(long*)A[j] == *(long*)pivot)
            break;

    // swap it with the right most value in A
    temp = A[j];
    A[j] = A[right];
    A[right] = temp;

    // do the partition
    for (j = 0; j < right; j++){
        if (*(long*)A[j] < *(long*)pivot){
            temp = A[i];
            A[i] = A[j];
            A[j] = temp;
            i++; // post increment i
        }
    }

    // store the pivot in place
    temp = A[i];
    A[right] = A[i];
    A[i] = temp;

    // return the index of the pivot
    return i;
}

这是另一种可能的实施方式

int partition(void **A, int n, void *pivot){
    void * temp;
    int left = 0, j = 0;
    int right = n-1;
    int i = left;

    // do the partition
    for (j = 0; j < n; j++){
        if (*(long*)A[j] < *(long*)pivot){
            temp = A[i];
            A[i] = A[j];
            A[j] = temp;
            i++; // post increment i
        }
    }
    // At this stage the pivot is somewhere in the range A[i] to A[right]

    // Lets find it and put it in A[i] if it's not already there
    if (*(long*)A[i] != *(long*)pivot){
        for (j = i+1; j < n; ++j){
            if (*(long*)A[j] == *(long*)pivot){
                temp = A[i];
                A[i] = A[j];
                A[j] = temp;
                break;
            }
        }
    }

    // return the index of the pivot
    return i;
}

答案 1 :(得分:0)

您的代码中存在明显的错误。你的myQuickSort函数将索引的整数推送并弹出到数组A中。但是&#34; partition&#34;我不知道整个阵列;它返回的值是相对于给定它的数组的开始。

假设您对包含200个项目的数组进行排序,并最终将范围从100传递到200以进行分区。如果它在中间分区,它不会像你期望的那样返回150,而是50。

我想知道您是否真的尝试过调试代码。