C阵列分区

时间:2014-04-28 16:18:39

标签: c quicksort partition

我正在尝试在阵列上使用快速排序,但我并不完全确定我做错了什么。我的数字顺序应为

  

-2 0 1 4 7 9 11 12 15

但是我得到了:

  

0 1 4 7 15 12 11 9 -2

这是我的分区代码:

int partition( int* a, int left, int right)
{
    int pivot, leftPoint, rightPoint, temp;
    pivot = a[left];
    leftPoint = left;
    rightPoint = right + 1;

    while(rightPoint > leftPoint)
    {
        while(a[leftPoint] <= pivot && leftPoint <= right)
            leftPoint ++;
        while(a[rightPoint] > pivot)
            rightPoint --;
        temp = a[leftPoint]; 
        a[leftPoint] = a[rightPoint]; 
        a[rightPoint] = temp;
    }
    temp = a[left];
    a[left] = a[rightPoint];
    a[rightPoint] = temp;
    return rightPoint;
}

有人可以帮我解释我的算法有什么问题吗?

编辑: 这是我的初始数组:

  

7 12 1 -2 0 15 4 11 9

我将快速排序称为

quicksort(a, 0, 8);

这是我的快速排序的实现:

void quickSort( int a[], int low, int high)
{
   int pivotPoint;
   if(low < high)
   {
       // divide and conquer
        pivotPoint = partition( a, low, high);
        quickSort( a, low, pivotPoint);
        quickSort( a, pivotPoint + 1, high);
   }
}

2 个答案:

答案 0 :(得分:1)

您似乎正在使用分区的第一个元素作为阈值。那么

leftPoint = left;
rightPoint = right + 1;

在这里你加入它。

temp = a[left];
a[left] = a[rightPoint];
a[rightPoint] = temp;

在这里结束你与分区的中间交换。你需要先排除threshhold,其次不要超出数组:

leftPoint = left+1;
rightPoint = right;

编辑您应该检查阈值是否小于下一个元素,并且只有在不是真的时才交换它:

if(a[left+1] < pivot) {
    temp = a[left];
    a[left] = a[rightPoint];
    a[rightPoint] = temp;
    rightPoint = left;
}

如果数组已经排序,则分区将失败。

编辑结束)

作为小型优化

    pivotPoint = partition( a, low, high);
    quickSort( a, low, pivotPoint);
    quickSort( a, pivotPoint + 1, high);

您可以在这里完全排除阈值:

    quickSort( a, low, pivotPoint-1);

答案 1 :(得分:0)

有了额外的信息,问题几乎肯定在于:

rightPoint = right + 1;

当您进入(a, 0, 8)的分区循环时,您需要将a[9]与透视值进行比较,这是个坏消息,因为有效索引为a[0]到{{ 1}}。

此处您的代码已转换为SSCCE(Short, Self-Contained, Correct Example):

a[8]

运行时,其中一个断言触发:

#include <stdio.h>
#include <assert.h>

static
int partition(int *a, int left, int right)
{
    int pivot, leftPoint, rightPoint, temp;
    pivot = a[left];
    leftPoint = left;
    rightPoint = right + 1;

    while (rightPoint > leftPoint)
    {
        while (a[leftPoint] <= pivot && leftPoint <= right)
            leftPoint++;
        while (a[rightPoint] > pivot)
            rightPoint--;
        assert(a[leftPoint] != -99 && a[leftPoint] != +99);
        assert(a[rightPoint] != -99 && a[rightPoint] != +99);
        assert(leftPoint >= left && leftPoint <= right);
        assert(rightPoint >= left && rightPoint <= right);
        temp = a[leftPoint];
        a[leftPoint] = a[rightPoint];
        a[rightPoint] = temp;
    }
    temp = a[left];
    a[left] = a[rightPoint];
    a[rightPoint] = temp;
    return rightPoint;
}

static
void quickSort( int a[], int low, int high)
{
    int pivotPoint;
    if (low < high)
    {
        // divide and conquer
        pivotPoint = partition( a, low, high);
        quickSort( a, low, pivotPoint);
        quickSort( a, pivotPoint + 1, high);
    }
}

int main(void)
{
    int aplus[] =
    {
        +99, +99, +99,
        7, 12, 1, -2, 0, 15, 4, 11, 9,
        -99, -99, -99
    };
    int *a = aplus + 3;

    quickSort(a, 0, 8);
    return 0;
}