快速排序实现以及相关笔试题

来源:互联网 发布:福岛核电站隐瞒知乎 编辑:程序博客网 时间:2024/04/26 05:35

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);elsereturn j;}



原创粉丝点击