快速排序
该方法的基本思想是:
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
C++实现,一般方案
时间复杂度
O(n2)
O
(
n
2
)
void quicksort(int data[], int start, int end)
{
if (start == end)
return;
int t = start;
for (int i = start + 1; i <= end; )
{
if (data[i] >= data[t])
i++;
else if (data[i] < data[t])
{
int temp = data[i];
int j = i;
while (j > start)
{
data[j] = data[j - 1];
j--;
}
data[j] = temp;
i++;
t++;
}
}
if (t > start)
quicksort(data, start, t - 1);
if (t < end)
quicksort(data, t + 1, end);
}
// 测试
int main()
{
int data[] = {9, 3, 1, 5, 3, 6, 4};
int n = sizeof(data)/sizeof(data[0]);
printf("排序前:\n");
for (int i = 0; i<n; i++)
printf("%3d", data[i]);
quicksort(data, 0, n - 1);
printf("排序后:\n");
for (int i = 0; i<n; i++)
printf("%3d", data[i]);
printf("\n");
return 0;
}
C实现,经典方案
复杂度:
O(N∗log(N))
O
(
N
∗
log
(
N
)
)
#include <stdio.h>
#include <malloc.h>
typedef int KeyType;
typedef struct
{
KeyType key;
}DataType;
void quicksort(DataType a[] , int low , int high)
{
int i = low ,j = high ;
DataType temp = a[low] ;///取第一个元素作为比较标准
while(i < j)
{
while(i < j && temp.key <= a[j].key) j-- ;///右端扫描
if(i < j)
{
a[i] = a[j] ;
i++ ;
}
while(i < j && temp.key > a[i].key) i++ ;///左端扫描
if(i < j)
{
a[j] = a[i] ;
j-- ;
}
}
a[i] = temp ;
if(low < i) quicksort(a , low , i-1);
if(high > j) quicksort(a , j+1 , high);
}
// 测试
int main()
{
DataType *t;
int i, n;
printf("请输入测试数据数组长度: ");
scanf("%d",&n);
t = (DataType *)malloc(sizeof(int) * n);
getchar();
printf("依次输入数据元素:\n");
for(i=0;i<n;i++)
scanf("%d",&t[i].key);
quicksort(t,0,n-1);
printf("排序后的结果:\n");
for(i=0;i<n;i++)
printf("%3d",t[i].key);
}
上述方案的区别在于:当出现比选定数字小的元素时,需要对数组移位。
C++的实现采用从前往后遍历,遇到小于选定数字的元素时,先将前面的元素往后移一位,再将小数字放在最前;
C的实现采用从两头遍历,从后开始遍历时只找比选定数字小的,找到后互换位置;然后从前开始遍历只找比选定数字大的,找到后互换位置。