快排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

有一个黑箱子,里面会按升序存储整数,你可以对黑箱子下达下面的指令:
a. ADD n 将n加入黑箱子
b. Get 获得一个数,这个数在黑箱子里的序号(从0开始计数)是Get的出现次数。
黑箱子中最初存了一个数0,现给你一个操作序列,要你输出Get命令时获的那个数。


输入:

每行是一个命令,如果命令是”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>
#include <math.h>
#include <string.h>
#include <stdlib.h>
//qsort(a, 1000, sizeof(int), cmp);
//其中cmp函数应写为:
int cmp(const void *a, const void *b)
{
    return *(int*)a - *(int*)b; //由小到大排序
    //return *(int *)b - *(int *)a; 由大到小排序
}
char string[10000];
int number[1000000];

int main()
{
    
    int i,n,j,sum,num,temp,flag;
    flag=0;
    number[0]=0;
    i=0;
    sum=0;
    num=0;
    scanf("%s",string);
    while(string[0]!='E')
    {
        if(string[0]=='A')
        {
            scanf("%d",&n);
            num++;
            number[num]=n;
            qsort(number,num+1, sizeof(int),&cmp);
            /*for(i=0;i<num;i++)
            {printf("%d",number[i]);
            }*/
        }
        if(string[0]=='G')
        {
            sum++;
            printf("%d\n",number[sum]);    
        }
        scanf("%s",string);
        if(string[0]=='E')
        {
            return 0;
        }
        
    }
    return 0;
}

//**

          for(i=0;i<num-1;i++)
            {
                for(j=0;j<num-i;j++)
                {
                    if(number[j]>number[j+1])
                    {
                    temp=number[j];
                    number[j]=number[j+1];
                    number[j+1]=temp;
                    }
                }
            }

  **//

冒泡排序

PS:虽然还是超时了,55555,但用来理解还不错

不超时代码:

#include <stdio.h>
char string[10000];
int number[1000000];
int main()
{
int num,add,get,i;
number[0]=0;
num=add=get=0;
scanf("%s",string);//注意空格即scanf字符串输入结束
while(get<=add+1)//判断条件而已,能连续输入即可
{
if(string[0]=='E')
{
return 0;
}
if(string[0]=='A')
{
add++;//计算输入的数字个数
scanf("%d",&num);
i=add-1;
while(number[i]>num&&i>=0)//每输入一个就比较一次,这样就不会超时了。类似与冒泡排序
{
number[i+1]=number[i];
i--;
}
number[i+1]=num;
}else
{
get++;//计算get个数
printf("%d\n",number[get]);//输出对应的序号的数
}
scanf("%s",string);
if(string[0]=='E')
{
return 0;
}

}
return 0;
}

嗯嗯,再来一道  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 <stdlib.h>
#include <string.h>
int cmp(const void *a, const void *b)
{
    return *(int*)a - *(int*)b; //由小到大排序
    //return *(int *)b - *(int *)a; 由大到小排序
}
int main()
{
    long long int k,n,i,j,number[20000];
    scanf("%I64d",&k);
    while(k--)
    {
        scanf("%I64d",&n);
        memset(number,0,sizeof(number));//清零
        for(i=0;i<n;i++)
        {
            scanf("%I64d",&number[i]);
        }
         qsort(number,n, sizeof(long long int),&cmp);//快排
        printf("%I64d\n",number[(n-1)/2]);//取中间的
        
    }
    return 0;
}

再参照上面的思路写一份代码

#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

posted @ 2019-12-25 19:36  adsry  阅读(157)  评论(0)    收藏  举报