zoukankan      html  css  js  c++  java
  • 快速排序实现以及相关笔试题

    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;
    }
    



  • 相关阅读:
    ssh反向代理+正向代理
    用 Java 撸了一款 SSH 客户端,真香啊!
    python清洗字符串
    欢迎来到 ZooKeeper 动物世界
    开篇:免费开源的趣讲 ZooKeeper 教程(连载)
    记忆中的像素块褪色了吗?用开源的体素编辑器重新做个 3D 的吧!
    不用再等后端的接口啦!这个开源项目花 2 分钟就能模拟出后端接口
    区块链技术在国外基础教育中的应用
    区块链在教育中的应用
    《敏捷开发培训考试》考试题目及答案
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3206384.html
Copyright © 2011-2022 走看看