快速排序实现无法正常工作

时间:2014-03-20 11:39:55

标签: c sorting

我试图在C中实现快速排序,我几乎设法做到这一点,但仍然存在一些我无法识别的问题。该计划似乎忘了"一些数字,它们处于错误的位置。

这是我的代码:

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

void quicksort(int* vettore, int a, int b);
int partition(int* vettore, int a, int b);

int main() {
    int vettore[10];
    int contatore;
    srand(time(NULL));
    printf("ESEMPIO DI IMPLEMENTAZIONE DI QUICK SORT\n\n");
    for(contatore=0;contatore<10;contatore++){
        vettore[contatore]=rand()%10+1;
    }
    printf("Vettore NON ordinato:\n");
    for(contatore=0;contatore<10;contatore++)
        printf("\nElemento n. %i: %i", contatore+1, vettore[contatore]);
    quicksort(vettore, 0, 9);
    printf("\n\nVettore ordinato:\n");
    for(contatore=0;contatore<10;contatore++)
        printf("\nElemento n. %i: %i", contatore+1, vettore[contatore]);
    printf("\n\n");
    system("pause");
    return 0;
}

void quicksort(int* vettore, int a, int b) {
    int q;
    if(a<b){
        q=partition(vettore, a, b);
        quicksort(vettore, a, q);
        quicksort(vettore, q+1, b);
    }
    return;
}

int partition(int* vettore, int a, int b) {
    int i, j, pivot, temp1=0, temp2=0;
    pivot=vettore[a];
    i=a;
    j=b;
    while(i<j) {
        while(vettore[i]<pivot && i<j && i<b)
            i++;
        while(vettore[j]>=pivot && i<j && j>a)
            j--;
        if(i<j){
            temp1=vettore[i];
            temp2=vettore[j];
            vettore[i]=temp2;
            vettore[j]=temp1;
            i++;
            j--;
        }
    }
    return i;
}

2 个答案:

答案 0 :(得分:0)

您没有在分区末尾将枢轴交换到正确的位置。枢轴仍在vettore[a]。您应该在分区末尾将vettore[a]vettore[i]交换。制作如下功能:

void swap(int *a, int *b)
{
  int temp = *a;
  *a = *b;
  *b = temp;
} 

并将其用于交换将使您的代码更清晰,更易于阅读。例如,if(i<j)块可以修改为:

if (i < j)
{
  swap(&a[i], &a[j]);
  i++;
  j--;
}

修改

上面有一些错误。我清理了你的代码。这有效:

void quicksort(int* vettore, int a, int b) {
    int q;
    if(a < b){
        q = partition(vettore, a, b);
        quicksort(vettore, a, q-1);
        quicksort(vettore, q+1, b);
    }
    return;
}

int partition(int* vettore, int a, int b) {
    int i = a, j = b+1;
    while(true) {
        while (vettore[++i] < vettore[a])
            if (i == b) break;
        while (vettore[a] < vettore[--j])
            if (j == a) break;

        if (i >= j) break;
        swap(&vettore[i], &vettore[j]);
    }

    swap(&vettore[a], &vettore[j]);
    return j;
}

最重要的是维护不变量。如果维护不变量,则更容易推理代码。此外,清洁代码是必要的。上面分区函数中的不变量是:

  • vettore [lo]是支点。
  • vettore [lo + 1] .. vettore [i]不到支点。
  • vettore [i + 1] .. vettore [j-1]是看不见的。
  • vettore [j] to vettore [b]大于枢轴 在while循环的每次迭代之前以及整个循环之后,不变量都是真的。

答案 1 :(得分:0)

如果有人感兴趣,我写了一个更简单的代码版本:

int partition(int* vettore, int a, int b) {
int i, j, pivot, temp;
pivot=vettore[a];
i=a;
j=b;
while(i<j) {
    while(vettore[i]<pivot && i<b)
        i++;
    while(vettore[j]>=pivot && j>a)
        j--;
    if(i<j){
        temp=vettore[i];
        vettore[i]=vettore[j];
        vettore[j]=temp;
    }
}
temp=vettore[a];
vettore[a]=vettore[j];
vettore[j]=temp;
return j;

}