在C赋值中,我需要使用堆栈实现快速排序,而不需要递归。
这是函数头(arr是要排序的数组,size是它的大小):
void StackBasedQuickSort(int* arr, int size)
假设一个工作的Stack结构,以及以下工作函数(作为asignment的一部分提供给我们,不能更改):
CreateStack(int size)
- 创建一个给定大小的堆栈。
QuicksortDataStructureLimit(int size)
- 返回堆栈所需的大小,由2 * ceil(log(size))计算。
IsStackEmpty(Stack* stack)
- 如果stack为空则返回TRUE,否则返回false。
IsStackFull(Stack* stack)
- 如果堆栈已满,则返回TRUE,否则返回false。
IsValidSubArray(int p, int r, int size)
- 如果(0 <= p&lt; r&lt; size)则返回TRUE,否则返回
MaybePushIndices(Stack* stack, int p, int r, int size)
- 如果是一个有效的子数组(见5),则将p和r推送到堆栈。否则,什么都不做。
Pop(Stack* stack)
- 从堆栈中弹出一个整数。
SwapIndices(int* arr, int p, int q)
- 交换数组中的2个元素。
我还实施了分区功能,我非常肯定有效:
int Partition(int* arr, int p, int r) {
int pivot = arr[r];
int q = p;
int j;
for (j = p; j < r; j++) {
if (arr[j] < pivot) {
SwapIndices(arr, q, j);
q++;
}
}
SwapIndices(arr, q, r);
return q;
}
我设法使用两种不同的方式实现快速排序:
第一种方式:
void StackBasedQuickSort(int* arr, int size) {
Stack* stack = CreateStack(QuicksortDataStructureLimit(size));
MaybePushIndices(stack, 0, size - 1, size);
while (!IsStackEmpty(stack)) {
q = Pop(stack);
p = Pop(stack);
r = Partition(arr, p, q);
if (IsStackFull(stack)) // for debugging
printf("Stack is full(1st attempt)\n");
MaybePushIndices(stack, p, r - 1, size);
if (IsStackFull(stack)) // for debugging
printf("Stack is full(2nd attempt)\n");
MaybePushIndices(stack, r + 1, q, size);
}
FreeStack(stack);
}
第二种方式:
void StackBasedQuickSort(int* arr, int size) {
Stack* stack = CreateStack(QuicksortDataStructureLimit(size));
p = 0;
r = size - 1;
if (!(IsValidSubArray(p, r, size))) return;
do{
while (IsValidSubArray(p, r, size)) {
q = Partition(arr, p, r);
PrintStackQuickSortState(stack, arr, p, q, r, size);
if (IsStackFull(stack) && IsValidSubArray(q + 1, r, size)) // for debugging
printf("STACK FULL!\n");
MaybePushIndices(stack, q + 1, r, size);
r = q - 1;
}
if (!(IsStackEmpty(stack))) {
r = Pop(stack);
p = Pop(stack);
}
else
break;
} while (IsValidSubArray(p, r, size));
FreeStack(stack);
}
现在,这是我的问题: 两种方式都可以使用更大的堆栈,但两种方式都不能使用给定的堆栈大小,这是分配的一部分,无法更改(即第一种方式给出了#34;堆栈已满(第二次尝试) &#34;警告,第二种方式给出&#34; STACK FULL!&#34;警告,在给出警告时排序不起作用但在没有给出警告时起作用。)
另外,请注意我只能更改Partition和StackBasedQuickSort函数的实现。
有没有办法以一种不需要超过2 * ceil(log(size))大小的堆栈的方式实现这种基于堆栈的快速排序?
谢谢!
编辑: 为了在堆栈上节省更多空间,我实现了一种算法,将较小部分的索引推送到堆栈并在较大部分上迭代运行,但我仍在堆栈上使用太多空间(即我得到一个&#34; STACK FULL!&#34;输出,但是当我不这样做时算法运行良好。
新代码:
Stack* stack = CreateStack(QuicksortDataStructureLimit(size));
int p = -1, q = -1, r = -1;
p = 0;
r = size - 1;
if (!(IsValidSubArray(p, r, size)))
return;
else
q = Partition(arr, p, r);
while (1){ // will break when stack is empty
while (IsValidSubArray(p, q - 1, size) || IsValidSubArray(q + 1, r, size)){
if (q - 1 - p > r - q - 1){ // left > right (push right, iterate left)
if (IsValidSubArray(q + 1, r, size) && IsStackFull(stack))
printf("STACK FULL!\n");
MaybePushIndices(stack, q + 1, r, size);
r = q - 1;
q = Partition(arr, p, r);
}
else{ // right >= left (push left, iterate right)
if (IsValidSubArray(p, q - 1, size) && IsStackFull(stack))
printf("STACK FULL!\n");
MaybePushIndices(stack, p, q - 1, size);
p = q + 1;
q = Partition(arr, p, r);
}
}
if (!(IsStackEmpty(stack))){
r = Pop(stack);
p = Pop(stack);
if (IsValidSubArray(p, r, size))
q = Partition(arr, p, r);
PrintStackQuickSortState(stack, arr, p, q, r, size);
}
else
break;
}
FreeStack(stack);`
有人可以就这项工作提出建议吗?