快速排序是由冒泡排序改进而得的,相比冒泡排序,快速排序的一次交换可能消除多个逆序。其平均时间复杂度为O(nlog2n),空间复杂度最好情况下为O(log2n),最坏情况下为O(n)。适用于顺序结构,不适用于链式结构,不稳定,适合于初始记录无序,n比较大的情况。
下面是实现代码:
首先是预定义和类型定义:
#define OK 1
#define ERROR 0
typedef int Status;
typedef int ElemType;
typedef struct{
ElemType *elem;
int length;
}SqList;
顺序表的插入:
Status EnSqList(SqList *L, ElemType e, int i)
{
if (i<1 || i>(L->length + 1))
return ERROR;
L->elem[i] = e;
L->length++;
return OK;
}
快速排序算法:
int Partition(SqList *L, int low, int high)
{
L->elem[0] = L->elem[low];
while (low < high)
{
while (low < high&&L->elem[high] >= L->elem[0])
high--;
L->elem[low] = L->elem[high];
while (low < high&&L->elem[low] <= L->elem[0])
low++;
L->elem[high] = L->elem[low];
}
L->elem[low] = L->elem[0];
return low;
}
void QSort(SqList *L, int low, int high)
{
int pivotloc;
if (low < high)
{
pivotloc = Partition(L, low, high);
QSort(L, low, pivotloc - 1);
QSort(L, pivotloc + 1, high);
}
}
void QuickSort(SqList *L)
{
QSort(L, 1, L->length);
}
Partition()函数:
先将以low为下标的元素保存在下标为0的元素中,当low小于high时,则执行循环:先从high开始,逐步检查是否存在元素比下标为0的元素小的值,若在low大于high之前有这样的元素存在,即将这个元素的值赋值给下标为low的元素(low的值在此之前已经储存在其他位置,或下标为0的位置,或此次循环开始时high的位置);同理,若在low大于high之前有元素大于下标为0的元素,则将其值赋值给下标为high的元素值。
循环结束后,将下标为0的元素值赋值给下标为low的元素值,此时下标low的元素必然为最终排序后该位置的元素。
QSort()函数:
如果low<high,则将引用的Partition()函数的返回值赋值给pivotloc,上面说过,pivotloc位置的元素事实上已经是最终排序后该位置的元素,即这个元素已经到达应该到达的位置,故将其左右的数据作为两个数组,然后递归应用QSort()对左右数组进行排序。
QuickSort()函数:
调用QSort()。
加入main()函数:
int main(void)
{
int n, i;
ElemType e;
SqList L;
L.length = 0;
printf("输入元素个数:");
scanf("%d", &n);
L.elem = (int *)malloc(sizeof(int)*n);
srand((int)time(0));
for (i = 1; i <= n; i++)
{
e = rand();
if (EnSqList(&L, e, i) == ERROR)
printf("错误\n");
}
printf("原数组:");
for (i = 1; i <= n; i++)
printf("%d ", L.elem[i]);
printf("\n");
QuickSort(&L);
printf("排序后:");
for (i = 1; i <= n; i++)
printf("%d ", L.elem[i]);
printf("\n");
return 0;
}