排序算法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;
}
}
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);
}
}