/*快排 - 遞歸實現
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;
}
}
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);
}
{
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;
nlogn
*/
typedef struct sortFlag
{
size_t start;
size_t len;
}stSortFlag;
typedef struct st_Stack
{
size_t iCount;
stSortFlag* stSort;
}stStack;
{
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;
{
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;
}
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);
}
}
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);
}
}