快排QSORT,,冒泡
快速排序是一种用的最多的排序算法,在C语言的标准库中也有快速排序的函数,下面说一下详细用法。
qsort函数包含在<stdlib.h>中
qsort函数声明如下:
void qsort(void * base,size_t nmemb,size_t size ,int(*compar)(const void *,const void *));
参数说明:
base,要排序的数组
nmemb,数组中元素的数目
size,每个数组元素占用的内存空间,可使用sizeof函数获得
compar,指向函数的指针也即函数指针。这个函数用来比较两个数组元素,第一个参数大于,等于,小于第二个参数时,分别显示正值,零,负值。
下面看几个例子:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
void main(void)
{
int i;
int a[10]={0,1,2,3,4,5,6,7,8,9};
char b[10]={'a','b','c','d','e','f','g','h','i','j'};
double c[10]={0.1,0.2,0.9,0.5,0.3,0.6,0.7,0.8,1.1,1.2};
int cmp1(const void * a,const void * b)
{
return (*(int*)a-*(int*)b);//a>b 返回正值
}
int cmp2(const void * a,const void *b)
{
return(*(char*)a-*(char*)b);
}
int cmp3(const void * a,const void * b)
{
if(fabs(*(double*)a-*(double *)b)<1*exp(-20))
return 0;
else
return(((*(double*)a-*(double*)b)>0)?1:-1);
}
qsort(a,10,sizeof(int),&cmp1);//对于函数指针(指向函数的指针),直接传入函数名和函数名进行&
//运算都是可以的,因为在调用函数时也是取的函数的地址
qsort(b,10,sizeof(char),cmp2);
qsort(c,10,sizeof(double),cmp3);
for(i=0;i<10;i++)
printf("%d ",a[i]);
for(i=0;i<10;i++)
printf("%c ",b[i]);
for(i=0;i<10;i++)
printf("%lf ",c[i]);
}
————————————————
版权声明:以上为CSDN博主「赵子苍」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhaozicang/article/details/24174965
例如:
Description//XTU OJ 1048 |
||
有一个黑箱子,里面会按升序存储整数,你可以对黑箱子下达下面的指令:
每行是一个命令,如果命令是”ADD”,则后面空一格,有一个整数;如果命令是“END”表示命令结束。输入时保证GET命令不会越界,
每行输出一个整数,整数为对应Get获得值。 |
||
Sample Input |
||
ADD 3 GET ADD 1 GET ADD -4 ADD 2 ADD 8 GET GET ADD -1000 ADD 2 GET END |
||
Sample Output |
||
3 3 2 3 2 |
||
#include <stdio.h> //** for(i=0;i<num-1;i++) **// 冒泡排序 PS:虽然还是超时了,55555,但用来理解还不错 不超时代码: #include <stdio.h> |
嗯嗯,再来一道 XTU OJ 1049
Description |
||
John是个农场主,养了奇数头牛,每头牛的产奶量都不一样,John想知道产奶量最中间的的值是多少?
第一行是一个整数K,表示有多少个测试用例,以后每个测试用例占2行。每个测试用例的第一行为一个奇数n(1<=n<=9999),表示有多少头牛,第二行为n个正整数的序列,每个正整数不超过231-1,两个数之间有一个空格隔开
每行输出一个测试用例的结果。 |
||
Sample Input |
||
2 5 2 3 1 4 5 7 10 2 3 6 5 4 8 |
||
Sample Output |
||
3 5 |
||
代码: #include <stdio.h> |
再参照上面的思路写一份代码
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
long long int k,n,i,j,number[20000],num,l;
scanf("%I64d",&k);
while(k--)
{
scanf("%I64d",&n);
memset(number,0,sizeof(number));
for(i=0;i<n;i++)
{
scanf("%I64d",&number[i]);
num=number[i];
l=i-1;
while(number[l]>num&&l>=0)
{
number[l+1]=number[l];
l--;
}
number[l+1]=num;
}
printf("%I64d\n",number[(n-1)/2]);
}
return 0;
}
//还是得分情况,这个用了812ms,快排才78ms
再来一(亿)道
Description XTU OJ 1050 |
||
给你一个整数序列和若干个问题,问题是这个序列的第i个元素到第j个元素的片断中的第k大数是什么?比如说给你的序列为(1, 5, 2, 6, 3, 7, 4),问题是(2,5,3),则从第2个元素到第5个元素为(5,2,6,3),排序以后是(2,3,5,6),则第三个数是5。
第一行为两个整数n,m(1 <= n <= 100 000, 1 <= m <= 5 000),表示序列的元素个数和问题的个数,第二行为n个正整数的序列,每个整数为一个32位整数,两个数之间有一个空格隔开。以后m行为问题,每个问题由三个整数表示i,j,k,第i个元素到第j个元素的片断中的第k大数是什么?(元素序号从1开始计数,i<=j,1<=k<=j-i+1)
每行输出对应问题的结果。 |
||
Sample Input |
||
7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 7 3 |
||
Sample Output |
||
5 6 3 |
||
Source |
||
程序设计实践 | ||
Hint |
||
问题包括大量的输入输出,请使用C风格的输入输出(printf,scanf)。 |
一看,快排:
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmp(const void *a,const void *b)
{
return (*(int*)a-*(int*)b);
//return (*(int*)b-*(int*)a);
}
int number[111111];
int copy_number[111111];
int main()
{
int n,k,i,j,a,b,c;
scanf("%d%d",&n,&k);
memset(number,0,sizeof(number));
memset(copy_number,0,sizeof(copy_number));
for(i=0;i<n;i++)
{
scanf("%d",&number[i]);
}
while(k--)
{
scanf("%d%d%d",&a,&b,&c);
j=0;
for(i=a-1;i<=b-1;i++)
{
copy_number[j]=number[i];
j++;
}
qsort(copy_number,j,sizeof(int),&cmp);
printf("%d\n",copy_number[c-1]);
}
return 0;
}
超时,心态爆炸,没办法,看大佬的,大佬用了递推
PS:我太菜了
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*int cmp(const void *a,const void *b)
{
return (*(int*)a-*(int*)b);
//return (*(int*)b-*(int*)a);
}*/
int number[111111];
int copy_number[111111];
int sort (int copy_number[],int l,int h,int k)
{
int i=l,j=h,temp;//从两边到中间来比
if(i>=j)//如果i>j把第k个数输出来
return copy_number[i];
temp=copy_number[i];//把第一个数作为比较值
while(i<j){
while(copy_number[j]>=temp&&j>i)
j--;
if(j>i){
copy_number[i++]=copy_number[j];
}
while(copy_number[i]<=temp&&i<j)
i++;
if(i<j){
copy_number[j--]=copy_number[i];
}
}
copy_number[i]=temp;
if(i+1==k)return copy_number[i];//同理 输出第k个数
//实际上这里也不用递归,可以减少很多时间。重新赋值i,j就可以了.人比较懒,不去改了
if(i+1<k)
return sort(copy_number,i+1,h,k);
return sort(copy_number,l,i-1,k);
}
int main()
{
int n,k,i,j,a,b,c,key;
scanf("%d%d",&n,&k);
memset(number,0,sizeof(number));
memset(copy_number,0,sizeof(copy_number));
for(i=0;i<n;i++)
{
scanf("%d",&number[i]);
}
while(k--)
{
scanf("%d%d%d",&a,&b,&c);
j=0;
for(i=a-1;i<=b-1;i++)
{
copy_number[j]=number[i];
j++;
}
//qsort(copy_number,j,sizeof(int),&cmp);
key=sort(copy_number,0,j-1,c);
printf("%d\n",key);
}
return 0;
}
其实本质上还是快排函数
可以参考博文理解sort函数 :https://blog.csdn.net/sdp1103285470/article/details/85251798