c - 使用堆栈迭代快速排序

标签 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);
            }
        }
    }

最佳答案

显然这就是你想要实现的快速排序算法 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 作为数据透视索引,则不需要它。但这不是你所做的。

另请注意,您对 i (storeIndex) 进行了预增量,这是一个错误。您应该首先进行交换,然后增加 i。我通过使用后增量将交换和增量合并在一条指令中。因此交换 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;
}

你的函数 我不希望在 11 点举行的航空 session 上不负责任的销售。 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[right]中。

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;
}

关于c - 使用堆栈迭代快速排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29251789/

相关文章:

c - 使用数组的第一个元素作为顶部实现堆栈

Android 完成 Activity 并启动另一个

jQuery:无法迭代

c - C的二进制流解析库

c - 指向结构的指针

c - 具有节点优先级的 A* 寻路

c - 在C中生成集合的子集(非递归)

C栈数组问题

javascript 对象数组迭代

javascript - 循环 css div 在 javascript 中留下一个数组