使用c

时间:2017-06-08 17:11:41

标签: c algorithm stack quicksort

在C赋值中,我需要使用堆栈实现快速排序,而不需要递归。

这是函数头(arr是要排序的数组,size是它的大小):

void StackBasedQuickSort(int* arr, int size)

假设一个工作的Stack结构,以及以下工作函数(作为asignment的一部分提供给我们,不能更改):

  1. CreateStack(int size) - 创建一个给定大小的堆栈。

  2. QuicksortDataStructureLimit(int size) - 返回堆栈所需的大小,由2 * ceil(log(size))计算。

  3. IsStackEmpty(Stack* stack) - 如果stack为空则返回TRUE,否则返回false。

  4. IsStackFull(Stack* stack) - 如果堆栈已满,则返回TRUE,否则返回false。

  5. IsValidSubArray(int p, int r, int size) - 如果(0 <= p&lt; r&lt; size)则返回TRUE,否则返回

  6. MaybePushIndices(Stack* stack, int p, int r, int size) - 如果是一个有效的子数组(见5),则将p和r推送到堆栈。否则,什么都不做。

  7. Pop(Stack* stack) - 从堆栈中弹出一个整数。

  8. SwapIndices(int* arr, int p, int q) - 交换数组中的2个元素。

  9. 我还实施了分区功能,我非常肯定有效:

    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);`
    

    有人可以就这项工作提出建议吗?

0 个答案:

没有答案