快速排序实现以及相关笔试题
1 快速排序的实现
思想:指定划分元素,如key=data[l],然后i先由左至右遍历数组并同时判断与key的大小,比key大则停止遍历,再j从右向左开始遍历数组并同时判断与key的大小,比key小则停止,两趟比较后,比较i与j的大小,i>j则不交换两数,否则交换data[i]与data[j]。当i>j时交换data[j]与data[l],最后返回key的位置j。这是一次划分,再分别从l -- j-1 和 j+1 -- h重复上面的划分过程.
具体代码如下:
void exch(int &a, int &b) //交换两个元素
{
int temp = a;
a = b;
b = temp;
}
//划分位置
int partion(int *data, int l, int h)
{
int key = data[l];
int i=l, j=h+1;
while(1)
{
while(data[++i]<key) if(i==h) break;
while(data[--j]>key) if(j==l) break;
if(i>j) break;
exch(data[i], data[j]);
}
exch(data[l], data[j]);
return j;
}
//快速排序
void qsort(int *data, int l, int h)
{
if(l>h) return ;
int pivot=partion(data, l, h);
qsort(data, l, pivot-1);
qsort(data, pivot+1, h);
}
2.优化快速排序,使其实划分位置为随机的,即key的值数组中的随机数字
int Less(int a, int b)
{ return ((a<b)?1:0); }
void exch(int &a, int &b)
{ int temp=a; a=b; b=temp; }
int partion(int *data, int l, int h)
{
srand((unsigned)time(NULL));
exch(data[l+rand()%(h-l+1)], data[l]);
int i=l, j=h+1;
int pivot=data[l];
while(1)
{
while(Less(data[++i], pivot)) if(i==h) break;
while(!Less(data[--j], pivot)) if(j==l) break;
if(i>=j) break;
exch(data[i], data[j]);
}
exch(data[l], data[j]);
return j;
}
void sort(int *data, int l, int h)
{
if(l>=h) return ;
int pivot=partion(data, l, h);
sort(data, l, pivot-1);
sort(data, pivot+1, h);
}
3 使用快速排序的思想解决划分奇偶数的问题,是数组中奇数在前,偶数在后
思路:就是在划分数组的过程中,将划分起始位置元素除以0,能整除则停止由左向右的遍历,开始由右向左遍历,步骤与上述一样
代码如下
//使用快速排序的思想解决划分奇偶数问题
void pivot_event(int *data, int l, int h, bool (*pfun)(int)) //pfun函数指针指向isEvent函数
{
int key=data[l];
int i=l, j=h+1;
while(1)
{
while(!pfun(data[++i])) if(i==h) break;
while(pfun(data[--j])) if(j==l) break;
if(i>j) break;
exch(data[i], data[j]);
}
exch(data[l], data[j]);
}
4 使用快速排序的思想解觉输出数组中第k个大的数,或者第k个小的数
思路与快速排序的思想一模一样,在一次划分后的位置j,如果比k-1大,则在l -- j-1处继续划分数组;如果比k-1小,则在j+1 -- h处划分数组,直到j==k位置时停止划分数组
代码如下:
//使用快排思想找到数组的第k大的数
int pivot_k(int *data, int l, int k, int h, bool (*pfun)(int, int)) //pfun函数指针指向isLess函数
{
int key;
key = data[l];
int i=l, j=h+1;
while(1)
{
while(isLess(data[++i], key)) if(i==h) break;
while(!isLess(data[--j], key)) if(j==l) break;
if(i>j) break;
exch(data[i], data[j]);
}
exch(data[l], data[j]);
if(j<k-1)
pivot_k(data, j+1, k, h, isLess);
else if(j>k-1)
pivot_k(data, l, k, j-1, isLess);
else
return j;
}

浙公网安备 33010602011771号