排序算法C語言實現——快速排序的遞歸和非遞歸實現


/*快排 -  遞歸實現
nlogn
*/
/*
原理:
    快速排序(Quicksort)是對冒泡排序的一種改進。
    快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
*/
/*QuickSort_getKey:選取首元素、中間元素、尾元素這3個元素中間大小的元素,作為Key */
/*Key保存在數組首元素*/
void QuickSort_getKey(int *data, size_t len)
{
    size_t iMin,iMid,iMax;
    int iTmp=0;
   
    if((NULL == data) || (len < 3))
    {
        return;
    }
   
    iMin=0,iMid=len/2,iMax=len-1;
   
    if(data[iMin] > data[iMid])
    {
        iTmp=data[iMin];
        data[iMin]=data[iMid];
        data[iMid]=iTmp;
    }
    if(data[iMid] > data[iMax])
    {
        iTmp=data[iMid];
        data[iMid]=data[iMax];
        data[iMax]=iTmp;
    }
    /*至此iMax保存3者中最大的元素,我們要把中間大小的元素放在首元素位置*/
    if(data[iMid] > data[iMin])
    {
        iTmp=data[iMin];
        data[iMin]=data[iMid];
        data[iMid]=iTmp;
    }
}
void QuickSort_recursion(int* data, size_t len)
{
    size_t i=0,j=len-1;
    int key=0;
   
    if(NULL == data)
    {
        /*throw("Invalid Parameter");*/
        return;
    }
   
    if(len<=1)
    {
        return;/*遞歸結束標志*/
    }
   
    /*選取Key,置於數組首元素位置*/
    QuickSort_getKey(data, len);
   
    key=data[i];
    while(i<j)
    {
        while((key<=data[j]) && (i<j))
        {
            j--;
        }
        data[i]=data[j];
       
        while((key>=data[i]) && (i<j))
        {
            i++;
        }
        data[j]=data[i];
    }
    data[i]=key;
   
    QuickSort_recursion(data, i);
    QuickSort_recursion(data+i+1, len-i-1);
}
/*快排 -  非遞歸實現(棧)
nlogn
*/
typedef struct sortFlag
{
    size_t start;
    size_t len;
}stSortFlag;
typedef struct st_Stack
{
    size_t iCount;
    stSortFlag* stSort;
}stStack;
void QuickSort_no_recursion(int* data, size_t len)
{
    size_t i=0,j=0,iStart=0,iLen=0;
    int key=0;
    stStack stck;/*棧內每個元素均表示一段待排序的數組起始地址和長度*/
   
    if(NULL == data)
    {
        /*throw("Invalid Parameter");*/
        return;
    }
   
    if (len < 2)
    {
        return;
    }
   
    stck.iCount = 0;
    stck.stSort = NULL;
   
    /*最壞情況需要len個棧空間*/
    stck.stSort = (stSortFlag*)malloc(len * sizeof(stSortFlag));
    if(NULL == stck.stSort)
    {
        return;
    }
    stck.stSort[stck.iCount].start=0;
    stck.stSort[stck.iCount].len=len;
    ++stck.iCount;
   
    /*用棧代替遞歸
      每次用遞歸的時候均入棧
      每次運算的時候均出棧
      棧為空則完成排序
    */
    while(stck.iCount)
    {
        --stck.iCount;/*取一個元素進行排序,相當於出棧*/
        iStart=stck.stSort[stck.iCount].start;
        iLen=stck.stSort[stck.iCount].len;
        i=iStart;
        j=iStart+iLen-1;
       
        /*選取Key,置於數組首元素位置*/
        QuickSort_getKey(data+iStart, iLen);
        key=data[i];
       
        while(i<j)
        {
            while((key<=data[j]) && (i<j))
            {
                j--;
            }
            data[i]=data[j];
           
            while((key>=data[i]) && (i<j))
            {
                i++;
            }
            data[j]=data[i];
        }
        data[i]=key;
       
        if((i-iStart) > 1)
        {
            /*stck.stSort[stck.iCount].start=iStart;*/ /*值未變,此行語句可省略*/
            stck.stSort[stck.iCount].len=i-iStart;
            ++stck.iCount;
        }
       
        if((iStart+iLen-1-i) > 1)
        {
            stck.stSort[stck.iCount].start=i+1;
            stck.stSort[stck.iCount].len=iStart+iLen-i-1;
            ++stck.iCount;
        }
    }
   
    if(NULL != stck.stSort)
    {
        free(stck.stSort);
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM