我正在尝试在阵列上使用快速排序,但我并不完全确定我做错了什么。我的数字顺序应为
-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);
}
}
答案 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;
}