簡體   English   中英

如何優化這種非遞歸快速排序以減少堆棧使用(c語言)

[英]How can this non-recursive quicksort be optimized to reduce stack usage(c language)

這是一個實現quicksort的非遞歸程序,我用一個數組來模擬棧的實現,但是每次對數組的一部分進行排序,占用的空間呈指數級增長。 如何優化這個程序,使使用量更小? 像重用之前丟棄的空間(X已經被遍歷的地方)什么的,我真的很想弄清楚,提前謝謝你。

#include <stdio.h>
#include <stdlib.h>
int stack[1000];

int partion(int a[],int begin,int end)
{
    int l= begin;
    int r= end;
    int pole = a[begin];
    while(l<r)
    {
        while(l<r && a[r]>=pole)
            r--;
        if(l<r)
        {
            a[l] = a[r];
            l++;
        }
        while(l<r && a[l]<= pole)
            l++;
        if(l<r)
        {
            a[r] = a[l];
            r--;
        }
    }
    a[r]= pole;
    return r;
}

void nonRecursiveQuickSort(int a[], int begin, int end);
int main()
{
    int i;
    int a[10]={0,1,-3,4,2,6,-9,0,8,10};
    nonRecursiveQuickSort(a, 0, 10);
    for(i=0;i<10;i++)
    {
        printf("%d ",a[i]);
    }
}

void nonRecursiveQuickSort(int a[], int begin, int end)
{
    int l = begin;
    int r = end;

    //replace the stack with an array, which stores the split boundaries
    int x = 0;
    int y = 0;

    //add left boundary
    stack[y++] = l;
    //add right boundary
    stack[y++] = r;

    // If the left boundary is smaller than the right boundary, the data to be processed is indicated
    while (x < y)
    {
        // Simulate stack popout left boundary
        int left = stack[x++];
        //Simulate stack popout right boundary
        int right = stack[x++];
        // Call partition function 
        int pos = partion(a, left, right);
        //if Meet the conditions, repress the stack
        if (left < pos - 1)
        {
            stack[y++] = left;
            stack[y++] = pos - 1;
        }
        if (pos + 1 < right)
        {
            stack[y++] = pos + 1;
            stack[y++] = right;
        } 
    }
}

調用nonRecursiveQuickSort(a, 0, 10)是錯誤的,因為這會導致 a[10] 在partion被引用; 正確的是nonRecursiveQuickSort(a, 0, 9)

重用先前丟棄的空間(其中 X 已被遍歷)

為此,FIFO 命名stack中的索引xy將環繞在數組的末尾。 nonRecursiveQuickSort中循環的這個修改版本可以做到這一點,還進行了檢查以防止溢出:

    #define DIM sizeof stack / sizeof *stack    // DIM must be even
    while (x != y)
    {
        // Simulate stack popout left boundary
        int left = stack[x++];
        //Simulate stack popout right boundary
        int right = stack[x++];
        if (x == DIM) x = 0;    // wrap around
        // Call partition function 
        int pos = partion(a, left, right);
        //if Meet the conditions, repress the stack
        if (left < pos - 1)
        {
            stack[y++] = left;
            stack[y++] = pos - 1;
            if (y == DIM) y = 0;    // wrap around
            if (y == x) puts("FIFO full"), exit(1);
        }
        if (pos + 1 < right)
        {
            stack[y++] = pos + 1;
            stack[y++] = right;
            if (y == DIM) y = 0;    // wrap around
            if (y == x) puts("FIFO full"), exit(1);
        } 
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM