用递归法:代码简洁,但运行速度很慢;
用迭代法:代码略多,但运行速度很快。
本文快速排序方法:
用两个指针i和j,分别指向传进来的低位地址和高位地址。去中间的数为基准值。i从左向右移动,碰到比基准值小的数就继续+1,直至i所指向的数为不小于基准值为止。j从右向左移动,碰到比基准值大的数就继续-1,直至j所指向的数为不大于基准值为止。此时如果满足i小于等于j,就交换i和j所指向数的值,然后i+1,j-1。整个循环一直到i大于j才结束。这时分别将低地址和j,i和高地址分别传入这个函数实现递归。其中,递归返回的条件为低地址大于等于高地址。
如果用迭代的话,就要用到栈的特性。将高低地址分别压栈保存。每次循环开始时就从栈顶取出,一对高低地址进行排序,循环结束时要将两对高低地址分别压栈保存。直至栈中没有元素为止。
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 50 //栈的大小
int sl[SIZE];
int sr[SIZE];
int sp = 0;
//入栈
int PUSH(int A, int B)
{
sl[sp]=A;
sr[sp]=B;
sp++;
}
//出栈
int POP(int* pl, int* pr)
{
sp--;
*pl = sl[sp];
*pr = sr[sp];
}
//迭代法快速排序
void quicksort(int* a,int l,int r)
{
int i,j,p,t;
PUSH(l,r);
while(sp){ //栈空即跳出循环
POP(&l,&r);
i = l;
j = r;
p=a[(i+j)/2]; //设定基准值(随意设定,不一定是中间的数)
while(i<=j) {
while(a[i]<p)
i++;
while(a[j]>p)
j--;
if(i<=j){ //交换数
t=a[i];
a[i]=a[j];
a[j]=t;
i++;
j--;
}
}
//判断是否结束(当l=j时,只有一个元素,不需要排序;
//当l>j时,没有元素。不需要压栈)
if(l<j)
PUSH(l,j);
if(i<r)
PUSH(i,r);
}
}
//对应的递归法快速排序
void sort(int *a, int low, int high)
{
if(low>=high)
return;
int t;
int p = a[(low+high)/2];
int i = low;
int j = high;
while(i<=j){
while(a[i]<p)
i++;
while(a[j]>p)
j--;
if(i<=j){
t = a[i];
a[i] = a[j];
a[j] = t;
i++;
j--;
}
}
sort(a,low,j);
sort(a,i,high);
}
int main()
{
int a[9] = {34, -13, -12, 33, 0, 12, 9, 4, 18};
quicksort(a,0, 8); //两种排序只用一种即可
// sort(a,0,8);
int i;
for(i=0; i<9; i++)
printf("%d\t", a[i]);
printf("\n");
return 0;
}
结果: