算法思想
步骤
基准的选取
选取第一个或最后一个元素作为基准都不好,因为如果元素事先已经排序好或以逆序排序,则基准不能达到分割的目的。
三数取中值选取基准(Median-of-Three Partitioning)
选取第一个元素,最中间元素,和最后一个元素,选取三个数的中间值作为基准。
int Median3(a[], int left, int right)
{
int center = (left + right) / 2;
if (a[left] > a[center])
swap(&a[left], &a[center]);
if (a[left] > a[right])
swap(&a[left], &a[right]);
if (a[center] > a[righht])
swap(&a[center], &a[right]);
swap(&a[center],&a[right-1]);
return a[right-1]; //return pivot
}
随机选取数值作为基准值
int RandomPivot(int a[], int left, int right)
{
srand(time(NULL));
int index = rand() % (right - left + 1) + left;
return a[index];
}
处理与基准相等的元素
当遇到与基准相等的元素时,停止继续扫描,进行交换。这样为了让基准能尽量将数组的两部分平分,而不出现两边长度严重失衡的现象。
递归法
void QuickSort(int a[], int n)
{
Qsort(a, 0, n-1);
}
#define cutoff (3)
void Qsort(int a[], int left, int right)
{
int i, j, pivot;
if (left + cutoff <= right) {
pivot = Median3(a, left, right);
i = left, j = right-1;
for (; ; ) {
while (a[++i] < pivot) ;
while (a[--j] > pivot) ;
if (i < j)
swap (&a[i], &a[j]);
else
break;
}
//退出时i 与 j相交,相交之处大于 pivot
swap(&a[i], &a[right-1]);
Qsort(a, left, i-1);
Qsort(a, i+1, right);
}
else
InserSort(a+left, right-left+1);
}
迭代法
算法思想见:快速排序(递归法与迭代法)
#define SIZE 100
int sl[SIZE], sr[SIZE];
int sp = 0;
void push(int l, int r)
{
if (sp >= SIZE)
printf("Full stack\n");
else {
sl[sp] = l;
sr[sp] = r;
sp++;
}
}
void pop(int *l, int *r)
{
if (sp <= 0)
printf("Empty stack\n");
else {
sp--;
*l = sl[sp];
*r = sr[sp];
}
}
Qsort(int a[], int l, int r)
{
int i, j, pivot;
push(l,r);
while (sp) {
pop(&l,&r);
pivot = Median3(a, l, r);
i = l;
j = r-1;
for (; ; ) {
while (a[++i] < pivot) ;
while (a[--j] > pivot) ;
if (i < j)
swap(&a[i],&a[j]);
else
break;
}
swap(&a[i],&a[r-1]);
if (l < i-1)
push(l,i-1);
if (i+1 < r)
push(i+1, r);
}
}
void QuickSort(int a[], int n)
{
Qsort(a, 0, n-1);
}