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个小的数
//使用快排思想找到数组的第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; }