zoukankan      html  css  js  c++  java
  • acm算法模板(2)

     

    数学问题:      

    1.精度计算——大数阶乘

    2.精度计算——乘法(大数乘小数)

    3.精度计算——乘法(大数乘大数)

    4.精度计算——加法

    5.精度计算——减法

    6.任意进制转换

    7.最大公约数、最小公倍数

    8.组合序列

    9.快速傅立叶变换(FFT) 

    10.Ronberg算法计算积分

    11.行列式计算

    12.求排列组合数

           

    字符串处理:      

    1.字符串替换

    2.字符串查找

    3.字符串截取

           

    计算几何:      

    1.叉乘法求任意多边形面积

    2.求三角形面积

    3.两矢量间角度

    4.两点距离(2D、3D

    5.射向法判断点是否在多边形内部

    6.判断点是否在线段上

    7.判断两线段是否相交

    8.判断线段与直线是否相交

    9.点到线段最短距离

    10.求两直线的交点

    11.判断一个封闭图形是凹集还是凸集

    12.Graham扫描法寻找凸包 

    数论:      

    1.x的二进制长度

    2.返回x的二进制表示中从低到高的第i

    3.模取幂运算

    4.求解模线性方程

    5.求解模线性方程组(中国余数定理)

    6.筛法素数产生器

    7.判断一个数是否素数 

           

    图论:      

    1.Prim算法求最小生成树

    2.Dijkstra算法求单源最短路径

    3.Bellman-ford算法求单源最短路径

    4.Floyd算法求每对节点间最短路径 

           

    排序/查找:      

    1.快速排序

    2.希尔排序

    3.选择法排序

    4.二分查找 

           

    数据结构:      

    1.顺序队列

    2.顺序栈

    3.链表

    4.链栈

    5.二叉树

         

    一、数学问题

    1.精度计算——大数阶乘

    语法:int result=factorial(int n);

    参数:

    n的阶乘

    返回值: 阶乘结果的位数

    注意:  

      本程序直接输出n!的结果,需要返回结果请保留long a[]

      需要 math.h

    源程序:  

      int factorial(int n)

    {

    long a[10000];

    int i,j,l,c,m=0,w; 

    a[0]=1; 

    for(i=1;i<=n;i++)

        { 

        c=0; 

        for(j=0;j<=m;j++)

            { 

            a[j]=a[j]*i+c; 

            c=a[j]/10000; 

            a[j]=a[j]%10000; 

        } 

        if(c>0) {m++;a[m]=c;} 

    w=m*4+log10(a[m])+1;

    printf(" %ld",a[m]); 

    for(i=m-1;i>=0;i--) printf("%4.4ld",a[i]);

    return w;

    2.精度计算——乘法(大数乘小数)

    语法:mult(char c[],char t[],int m);

    参数:

    c[] 被乘数,用字符串表示,位数不限

    t[] 结果,用字符串表示

    m 乘数,限定10以内

    返回值: null

    注意:  

      需要 string.h

    源程序:  

      void mult(char c[],char t[],int m)

    {

        int i,l,k,flag,add=0;

        char s[100];

        l=strlen(c);

        for (i=0;i<l;i++)

            s[l-i-1]=c[i]-'0'; 

        for (i=0;i<l;i++)

               {

               k=s[i]*m+add;

               if (k>=10) {s[i]=k%10;add=k/10;flag=1;} else {s[i]=k;flag=0;add=0;}

               }

        if (flag) {l=i+1;s[i]=add;} else l=i;

        for (i=0;i<l;i++)

            t[l-1-i]=s[i]+'0';

        t[l]='';

    }

    3.精度计算——乘法(大数乘大数)

    语法:mult(char a[],char b[],char s[]);

    参数:

    a[] 被乘数,用字符串表示,位数不限

    b[] 乘数,用字符串表示,位数不限

    t[] 结果,用字符串表示

    返回值: null

    注意:  

      空间复杂度为 o(n^2)

      需要 string.h

    源程序:  

      void mult(char a[],char b[],char s[])

    {

        int i,j,k=0,alen,blen,sum=0,res[65][65]={0},flag=0;

        char result[65];

        alen=strlen(a);blen=strlen(b); 

        for (i=0;i<alen;i++)

        for (j=0;j<blen;j++) res[i][j]=(a[i]-'0')*(b[j]-'0');

        for (i=alen-1;i>=0;i--)

            {

                for (j=blen-1;j>=0;j--) sum=sum+res[i+blen-j-1][j];

                result[k]=sum%10;

                k=k+1;

                sum=sum/10;

            }

        for (i=blen-2;i>=0;i--)

            {

                for (j=0;j<=i;j++) sum=sum+res[i-j][j];

                result[k]=sum%10;

                k=k+1;

                sum=sum/10;

            }

        if (sum!=0) {result[k]=sum;k=k+1;}

        for (i=0;i<k;i++) result[i]+='0';

        for (i=k-1;i>=0;i--) s[i]=result[k-1-i];

        s[k]='';

        while(1)

            {

            if (strlen(s)!=strlen(a)&&s[0]=='0') 

                strcpy(s,s+1);

            else

                break;

            }

    }

    4.精度计算——加法

    语法:add(char a[],char b[],char s[]);

    参数:

    a[] 被乘数,用字符串表示,位数不限

    b[] 乘数,用字符串表示,位数不限

    t[] 结果,用字符串表示

    返回值: null

    注意:  

      空间复杂度为 o(n^2)

      需要 string.h

    源程序:  

      void add(char a[],char b[],char back[])

    {

        int i,j,k,up,x,y,z,l;

        char *c;

        if (strlen(a)>strlen(b)) l=strlen(a)+2; else l=strlen(b)+2;

        c=(char *) malloc(l*sizeof(char));

        i=strlen(a)-1;

        j=strlen(b)-1;

        k=0;up=0;

        while(i>=0||j>=0)

            {

                if(i<0) x='0'; else x=a[i];

                if(j<0) y='0'; else y=b[j];

                z=x-'0'+y-'0';

                if(up) z+=1;

                if(z>9) {up=1;z%=10;} else up=0;

                c[k++]=z+'0';

                i--;j--;

            }

        if(up) c[k++]='1';

        i=0;

        c[k]='';

        for(k-=1;k>=0;k--)

            back[i++]=c[k];

        back[i]='';

    5.精度计算——减法

    语法:sub(char s1[],char s2[],char t[]);

    参数:

    s1[] 被减数,用字符串表示,位数不限

    s2[] 减数,用字符串表示,位数不限

    t[] 结果,用字符串表示

    返回值: null

    注意:  

      默认s1>=s2,程序未处理负数情况

      需要 string.h

    源程序:  

      void sub(char s1[],char s2[],char t[])

    {

        int i,l2,l1,k;

        l2=strlen(s2);l1=strlen(s1);

        t[l1]='';l1--;

        for (i=l2-1;i>=0;i--,l1--)

            {

            if (s1[l1]-s2[i]>=0) 

                t[l1]=s1[l1]-s2[i]+'0';

            else

                {

                t[l1]=10+s1[l1]-s2[i]+'0';

                s1[l1-1]=s1[l1-1]-1;

                }

            }

        k=l1;

        while(s1[k]<0) {s1[k]+=10;s1[k-1]-=1;k--;}

        while(l1>=0) {t[l1]=s1[l1];l1--;}

    loop:

        if (t[0]=='0') 

            {

            l1=strlen(s1);

            for (i=0;i<l1-1;i++) t[i]=t[i+1];

            t[l1-1]='';

            goto loop;

            }

        if (strlen(t)==0) {t[0]='0';t[1]='';}

    6.任意进制转换

    语法:conversion(char s1[],char s2[],long d1,long d2);

    参数:

    s[] 原进制数字,用字符串表示

    s2[] 转换结果,用字符串表示

    d1 原进制数

    d2 需要转换到的进制数

    返回值: null

    注意:  

      高于9的位数用大写'A'~'Z'表示,2~16位进制通过验证

    源程序:  

      void conversion(char s[],char s2[],long d1,long d2)

    {

        long i,j,t,num;

        char c;

        num=0;

        for (i=0;s[i]!='';i++)

            {

            if (s[i]<='9'&&s[i]>='0') t=s[i]-'0'; else t=s[i]-'A'+10;

            num=num*d1+t;

            }

        i=0;

        while(1)

            {

            t=num%d2;

            if (t<=9) s2[i]=t+'0'; else s2[i]=t+'A'-10;

            num/=d2;

            if (num==0) break;

            i++;

            }

        for (j=0;j<i/2;j++)

            {c=s2[j];s2[j]=s[i-j];s2[i-j]=c;}

        s2[i+1]='';

    }

    7.最大公约数、最小公倍数

    语法:resulet=hcf(int a,int b)、result=lcd(int a,int b)

    参数:

    a int a,求最大公约数或最小公倍数

    b int b,求最大公约数或最小公倍数

    返回值: 返回最大公约数(hcf)或最小公倍数(lcd

    注意:  

      lcd 需要连同 hcf 使用

    源程序:  

      int hcf(int a,int b)

    {

        int r=0;

        while(b!=0)

            {

            r=a%b;

            a=b;

            b=r;

            }

        return(a);

    lcd(int u,int v,int h)

    {

        return(u*v/h);

    }

    8.组合序列

    语法:m_of_n(int m, int n1, int m1, int* a, int head)

    参数:

    m 组合数C的上参数

    n1 组合数C的下参数

    m1 组合数C的上参数,递归之用

    *a 1~n的整数序列数组

    head 头指针

    返回值: null

    注意:  

      *a需要自行产生

      初始调用时,m=m1、head=0

      调用例子:求C(m,n)序列:m_of_n(m,n,m,a,0);

    源程序:  

      void m_of_n(int m, int n1, int m1, int* a, int head) 

        int i,t; 

        if(m1<0 || m1>n1) return; 

        if(m1==n1) 

            { 

            for(i=0;i<m;i++) cout<<a[i]<<' '; // 输出序列 

            cout<<' '; 

            return; 

            } 

        m_of_n(m,n1-1,m1,a,head); // 递归调用 

        t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t;

        m_of_n(m,n1-1,m1-1,a,head+1); // 再次递归调用 

        t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t;

    9.快速傅立叶变换(FFT

    语法:kkfft(double pr[],double pi[],int n,int k,double fr[],double fi[],int l,int il);

    参数:

    pr[n] 输入的实部 

    pi[n] 数入的虚部

    n,k 满足n=2^k

    fr[n] 输出的实部

    fi[n] 输出的虚部

    l 逻辑开关,0 FFT,1 ifFT

    il 逻辑开关,0 输出按实部/虚部;1 输出按模/幅角 

    返回值: null

    注意:  

      需要 math.h

    源程序:  

      void kkfft(pr,pi,n,k,fr,fi,l,il) 

    int n,k,l,il; 

    double pr[],pi[],fr[],fi[]; 

    {

        int it,m,is,i,j,nv,l0; 

        double p,q,s,vr,vi,poddr,poddi; 

        for (it=0; it<=n-1; it++) 

            {

             m=it; is=0; 

            for (i=0; i<=k-1; i++) 

                {j=m/2; is=2*is+(m-2*j); m=j;}

            fr[it]=pr[is]; fi[it]=pi[is]; 

            } 

        pr[0]=1.0; pi[0]=0.0; 

        p=6.283185306/(1.0*n); 

        pr[1]=cos(p); pi[1]=-sin(p); 

        if (l!=0) pi[1]=-pi[1]; 

        for (i=2; i<=n-1; i++) 

            {

           p=pr[i-1]*pr[1];

           q=pi[i-1]*pi[1]; 

            s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]); 

            pr[i]=p-q; pi[i]=s-p-q; 

            } 

        for (it=0; it<=n-2; it=it+2) 

            {

           vr=fr[it]; vi=fi[it]; 

            fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1]; 

            fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1]; 

            } 

        m=n/2; nv=2; 

        for (l0=k-2; l0>=0; l0--) 

            {

            m=m/2; nv=2*nv; 

            for (it=0; it<=(m-1)*nv; it=it+nv) 

                for (j=0; j<=(nv/2)-1; j++) 

                    {

                   p=pr[m*j]*fr[it+j+nv/2]; 

                    q=pi[m*j]*fi[it+j+nv/2]; 

                    s=pr[m*j]+pi[m*j]; 

                    s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]); 

                    poddr=p-q; poddi=s-p-q; 

                    fr[it+j+nv/2]=fr[it+j]-poddr; 

                    fi[it+j+nv/2]=fi[it+j]-poddi; 

                    fr[it+j]=fr[it+j]+poddr; 

                    fi[it+j]=fi[it+j]+poddi; 

                    } 

            } 

        if (l!=0) 

            for (i=0; i<=n-1; i++) 

                {

               fr[i]=fr[i]/(1.0*n); 

                fi[i]=fi[i]/(1.0*n); 

                } 

        if (il!=0) 

                for (i=0; i<=n-1; i++) 

                {

               pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]); 

                if (fabs(fr[i])<0.000001*fabs(fi[i])) 

                    {

                   if ((fi[i]*fr[i])>0) pi[i]=90.0; 

                    else pi[i]=-90.0; 

                    } 

                else 

                    pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306; 

                } 

        return; 

    10.Ronberg算法计算积分

    语法:result=integral(double a,double b);

    参数:

    a 积分上限

    b 积分下限

    function f 积分函数

    返回值: f在(a,b)之间的积分值

    注意:  

      function f(x)需要自行修改,程序中用的是sina(x)/x

      需要 math.h

      默认精度要求是1e-5

    源程序:  

      double f(double x)

        return sin(x)/x; //在这里插入被积函数 

    }

    double integral(double a,double b) 

        double h=b-a; 

        double t1=(1+f(b))*h/2.0;

        int k=1; 

        double r1,r2,s1,s2,c1,c2,t2; 

    loop: 

        double s=0.0; 

        double x=a+h/2.0; 

        while(x<b) 

            { 

            s+=f(x); 

            x+=h; 

            } 

        t2=(t1+h*s)/2.0;

        s2=t2+(t2-t1)/3.0;

        if(k==1)

          { 

            k++;h/=2.0;t1=t2;s1=s2;

            goto loop; 

            } 

        c2=s2+(s2-s1)/15.0; 

        if(k==2){ 

            c1=c2;k++;h/=2.0; 

            t1=t2;s1=s2; 

            goto loop; 

            } 

        r2=c2+(c2-c1)/63.0; 

        if(k==3){ 

            r1=r2; c1=c2;k++; 

            h/=2.0; 

            t1=t2;s1=s2;

            goto loop; 

            } 

        while(fabs(1-r1/r2)>1e-5){ 

            r1=r2;c1=c2;k++;

            h/=2.0; 

            t1=t2;s1=s2; 

            goto loop; 

            } 

        return r2;

    11.行列式计算

    语法:result=js(int s[][],int n)

    参数:

    s[][] 行列式存储数组

    n 行列式维数,递归用

    返回值: 行列式值

    注意:  

      函数中常数N为行列式维度,需自行定义

    源程序:  

      int js(s,n) 

    int s[][N],n; 

    {

        int z,j,k,r,total=0; 

        int b[N][N];/*b[N][N]用于存放,在矩阵s[N][N]中元素s[0]的余子式*/ 

        if(n>2)

            {

            for(z=0;z<n;z++) 

                {

                for(j=0;j<n-1;j++) 

                     for(k=0;k<n-1;k++) 

                            if(k>=z) b[j][k]=s[j+1][k+1];  else b[j][k]=s[j+1][k]; 

                if(z%2==0) r=s[0][z]*js(b,n-1); /*递归调用*/ 

                else r=(-1)*s[0][z]*js(b,n-1); 

                total=total+r; 

                } 

            } 

        else if(n==2)

           total=s[0][0]*s[1][1]-s[0][1]*s[1][0]; 

        return total; 

    12.求排列组合数

    语法:result=P(long n,long m); / result=long C(long n,long m);

    参数:

    m 排列组合的上系数

    n 排列组合的下系数

    返回值: 排列组合数

    注意:  

      符合数学规则:m<=n

    源程序:  

      long P(long n,long m)

    {

        long p=1;

        while(m!=0)

            {p*=n;n--;m--;}

        return p;

    long C(long n,long m)

    {

        long i,c=1;

        i=m;

        while(i!=0)

            {c*=n;n--;i--;}

        while(m!=0)

            {c/=m;m--;}

        return c;

    二、字符串处理

    1.字符串替换

    语法:replace(char str[],char key[],char swap[]);

    参数:

    str[] 在此源字符串进行替换操作

    key[] 被替换的字符串,不能为空串

    swap[] 替换的字符串,可以为空串,为空串表示在源字符中删除key[]

    返回值: null

    注意:  

      默认str[]长度小于1000,如否,重新设定设定tmp大小

      需要 string.h

    源程序:  

      void replace(char str[],char key[],char swap[])

    {

        int l1,l2,l3,i,j,flag;

        char tmp[1000];

        l1=strlen(str);

        l2=strlen(key);

        l3=strlen(swap);

        for (i=0;i<=l1-l2;i++)

            {

            flag=1;

            for (j=0;j<l2;j++)

                if (str[i+j]!=key[j]) {flag=0;break;}

            if (flag)

                {

                strcpy(tmp,str);

                strcpy(&tmp[i],swap);

                strcpy(&tmp[i+l3],&str[i+l2]);

                strcpy(str,tmp);

                i+=l3-1;

                l1=strlen(str);

                }

            }

    }

    2.字符串查找

    语法:result=strfind(char str[],char key[]);

    参数:

    str[] 在此源字符串进行查找操作

    key[] 被查找的字符串,不能为空串

    返回值: 如果查找成功,返回key在str中第一次出现的位置,否则返回-1

    注意:  

      需要 string.h

    源程序:  

      int strfind(char str[],char key[])

    {

        int l1,l2,i,j,flag;

        l1=strlen(str);

        l2=strlen(key);

        for (i=0;i<=l1-l2;i++)

            {

            flag=1;

            for (j=0;j<l2;j++)

                if (str[i+j]!=key[j]) {flag=0;break;}

            if (flag) return i;

            }

        return -1;

    3.字符串截取

    语法:mid(char str[],int start,int len,char strback[])

    参数:

    str[] 操作的目标字符串

    start 从第start个字符串开始,截取长度为len的字符

    len 从第start个字符串开始,截取长度为len的字符

    strback[] 截取的到的字符

    返回值: 0:超出字符串长度,截取失败;1:截取成功

    注意:  

      需要 string.h

    源程序:  

      int mid(char str[],int start,int len,char strback[])

    {

        int l,i,k=0;

        l=strlen(str);

        if (start+len>l) return 0;

        for (i=start;i<start+len;i++)

            strback[k++]=str[i];

        strback[k]='';

        return 1;

    三、计算几何

    1.叉乘法求任意多边形面积

    语法:result=polygonarea(Point *polygon,int N);

    参数:

    *polygon 多变形顶点数组

    N 多边形顶点数目

    返回值: 多边形面积

    注意:  

      支持任意多边形,凹、凸皆可

      多边形顶点输入时按顺时针顺序排列

    源程序:  

      typedef struct {

        double x,y;

    } Point; 

    double polygonarea(Point *polygon,int N)

    {

        int i,j;

        double area = 0;

        for (i=0;i<N;i++) {

            j = (i + 1) % N;

            area += polygon[i].x * polygon[j].y;

            area -= polygon[i].y * polygon[j].x;

            }

        area /= 2;

        return(area < 0 ? -area : area);

    }

    2.求三角形面积

    语法:result=area3(float x1,float y1,float x2,float y2,float x3,float y3);

    参数:

    x1~3 三角形3个顶点x坐标

    y1~3 三角形3个顶点y坐标

    返回值: 三角形面积

    注意:  

      需要 math.h

    源程序:  

      float area3(float x1,float y1,float x2,float y2,float x3,float y3)

    {

        float a,b,c,p,s;

        a=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));

        b=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));

        c=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));

        p=(a+b+c)/2;

        s=sqrt(p*(p-a)*(p-b)*(p-c));

        return s;

    }

    3.两矢量间角度

    语法:result=angle(double x1, double y1, double x2, double y2);

    参数:

    x/y1~2 两矢量的坐标

    返回值: 两的角度矢量

    注意:  

      返回角度为弧度制,并且以逆时针方向为正方向

      需要 math.h

    源程序:  

      #define PI 3.1415926

    double angle(double x1, double y1, double x2, double y2)

    {

        double dtheta,theta1,theta2; 

        theta1 = atan2(y1,x1);

        theta2 = atan2(y2,x2);

        dtheta = theta2 - theta1;

        while (dtheta > PI)

            dtheta -= PI*2;

        while (dtheta < -PI)

            dtheta += PI*2; 

        return(dtheta);

    }

    4.两点距离(2D、3D

    语法:result=distance_2d(float x1,float x2,float y1,float y2);

    参数:

    x/y/z1~2 各点的x、y、z坐标

    返回值: 两点之间的距离

    注意:  

      需要 math.h

    源程序:  

      float distance_2d(float x1,float x2,float y1,float y2) 

    {

        return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));

    }

    float distance_3d(float x1,float x2,float y1,float y2,float z1,float z2)

    {

        return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));

    }

    5.射向法判断点是否在多边形内部

    语法:result=insidepolygon(Point *polygon,int N,Point p);

    参数:

    *polygon 多边形顶点数组

    N 多边形顶点个数

    p 被判断点

    返回值: 0:点在多边形内部;1:点在多边形外部

    注意:  

      若p点在多边形顶点或者边上,返回值不确定,需另行判断

      需要 math.h

    源程序:  

      #define MIN(x,y) (x < y ? x : y)

    #define MAX(x,y) (x > y ? x : y)

    typedef struct {

        double x,y;

    } Point;

    int insidepolygon(Point *polygon,int N,Point p)

    {

        int counter = 0;

        int i;

        double xinters;

        Point p1,p2;

        p1 = polygon[0];

        for (i=1;i<=N;i++) {

            p2 = polygon[i % N];

            if (p.y > MIN(p1.y,p2.y)) {

                if (p.y <= MAX(p1.y,p2.y)) {

                    if (p.x <= MAX(p1.x,p2.x)) {

                        if (p1.y != p2.y) {

                            xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;

                            if (p1.x == p2.x || p.x <= xinters)

                                counter++;

                            }

                        }

                    }

                }

                p1 = p2;

            }

        if (counter % 2 == 0)

            return(OUTSIDE);

        else

            return(INSIDE);

    }

    6.判断点是否在线段上

    语法:result=Pointonline(Point p1,Point p2,Point p);

    参数:

    p1、p2 线段的两个端点

    p 被判断点

    返回值: 0:点在不在线段上;1:点在线段上

    注意:  

      若p线段端点上返回1

      需要 math.h

    源程序:  

      #define MIN(x,y) (x < y ? x : y)

    #define MAX(x,y) (x > y ? x : y) 

    typedef struct {

    double x,y;

    } Point;

    int FC(double x1,double x2)

    {

        if (x1-x2<0.000002&&x1-x2>-0.000002) return 1; else return 0;

    }

    int Pointonline(Point p1,Point p2,Point p)

    {

        double x1,y1,x2,y2;

        x1=p.x-p1.x;

        x2=p2.x-p1.x;

        y1=p.y-p1.y;

        y2=p2.y-p1.y;

        if (FC(x1*y2-x2*y1,0)==0) return 0;

        if ((MIN(p1.x,p2.x)<=p.x&&p.x<=MAX(p1.x,p2.x))&&

                (MIN(p1.y,p2.y)<=p.y&&p.y<=MAX(p1.y,p2.y)))

            return 1; else return 0;

    }

    7.判断两线段是否相交

    语法:result=sectintersect(Point p1,Point p2,Point p3,Point p4);

    参数:

    p1~4 两条线段的四个端点

    返回值: 0:两线段不相交;1:两线段相交;2两线段首尾相接

    注意:  

      p1!=p2;p3!=p4;

    源程序:  

      #define MIN(x,y) (x < y ? x : y)

    #define MAX(x,y) (x > y ? x : y) 

    typedef struct {

        double x,y;

    } Point;

    int lineintersect(Point p1,Point p2,Point p3,Point p4)

    {

        Point tp1,tp2,tp3;

        if ((p1.x==p3.x&&p1.y==p3.y)||(p1.x==p4.x&&p1.y==p4.y)||(p2.x==p3.x&&p2.y==p3.y)||(p2.x==p4.x&&p2.y==p4.y))

            return 2;

    //快速排斥试验

        if ((MIN(p1.x,p2.x)<p3.x&&p3.x<MAX(p1.x,p2.x)&&MIN(p1.y,p2.y)<p3.y<MAX(p1.y,p2.y))||

                (MIN(p1.x,p2.x)<p4.x&&p3.x<MAX(p1.x,p2.x)&&MIN(p1.y,p2.y)<p3.y<MAX(p1.y,p2.y)))

            ;else return 0;

    //跨立试验

        tp1.x=p1.x-p3.x;

        tp1.y=p1.y-p3.y;

        tp2.x=p4.x-p3.x;

        tp2.y=p4.y-p3.y;

        tp3.x=p2.x-p3.x;

        tp3.y=p2.y-p3.y;

        if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0) return 1; else return 0;

    }

    8.判断线段与直线是否相交

    语法:result=lineintersect(Point p1,Point p2,Point p3,Point p4);

    参数:

    p1、p2 线段的两个端点

    p3、p4 直线上的两个点

    返回值: 0:线段直线不相交;1:线段和直线相交

    注意:  

      如线段在直线上,返回 1

    源程序:  

      typedef struct {

        double x,y;

    } Point;

    int lineintersect(Point p1,Point p2,Point p3,Point p4)

    {

        Point tp1,tp2,tp3;

        tp1.x=p1.x-p3.x;

        tp1.y=p1.y-p3.y;

        tp2.x=p4.x-p3.x;

        tp2.y=p4.y-p3.y;

        tp3.x=p2.x-p3.x;

        tp3.y=p2.y-p3.y;

        if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0) return 1; else return 0;

    }

    9.点到线段最短距离

    语法:result=mindistance(Point p1,Point p2,Point q);

    参数:

    p1、p2 线段的两个端点

    q 判断点

    返回值: 点q到线段p1p2的距离

    注意:  

      需要 math.h

    源程序:  

      #define MIN(x,y) (x < y ? x : y)

    #define MAX(x,y) (x > y ? x : y)

    typedef struct {

        double x,y;

    } Point;

    double mindistance(Point p1,Point p2,Point q)

    {

        int flag=1;

        double k;

        Point s;

        if (p1.x==p2.x) {s.x=p1.x;s.y=q.y;flag=0;}

        if (p1.y==p2.y) {s.x=q.x;s.y=p1.y;flag=0;}

        if (flag)

            {

            k=(p2.y-p1.y)/(p2.x-p1.x);

            s.x=(k*k*p1.x+k*(q.y-p1.y)+q.x)/(k*k+1);

            s.y=k*(s.x-p1.x)+p1.y;

            }

        if (MIN(p1.x,p2.x)<=s.x&&s.x<=MAX(p1.x,p2.x))

            return sqrt((q.x-s.x)*(q.x-s.x)+(q.y-s.y)*(q.y-s.y));

        else

            return MIN(sqrt((q.x-p1.x)*(q.x-p1.x)+(q.y-p1.y)*(q.y-p1.y)),sqrt((q.x-p2.x)*(q.x-p2.x)+(q.y-p2.y)*(q.y-p2.y)));

    }

    10.求两直线的交点

    语法:result=mindistance(Point p1,Point p2,Point q);

    参数:

    p1~p4 直线上不相同的两点

    *p 通过指针返回结果

    返回值: 1:两直线相交;2:两直线平行

    注意:  

      如需要判断两线段交点,检验k和对应k1(注释中)的值是否在0~1之间,用在0~1之间的那个求交点

    源程序:  

      typedef struct {

       double x,y;

    } Point;

    int linecorss(Point p1,Point p2,Point p3,Point p4,Point *p)

    {

       double k;

       //同一直线

      if ((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x)==0&&

            (p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x)==0) return 2;

       //平行,不同一直线

      if ((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y)==0) return 0;

        k=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));

    //k1=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));

       (*p).x=p1.x+k*(p2.x-p1.x);

       (*p).y=p1.y+k*(p2.y-p1.y);

       return 1;//有交点}

    11.判断一个封闭图形是凹集还是凸集

    语法:result=convex(Point *p,int n);

    参数:

    *p 封闭曲线顶点数组

    n 封闭曲线顶点个数

    返回值: 1:凸集;-1:凹集;0:曲线不符合要求无法计算

    注意:  

      默认曲线为简单曲线:无交叉、无圈

    源程序:  

      typedef struct {

        double x,y;

    } Point;

    int convex(Point *p,int n)

    {

        int i,j,k;

        int flag = 0;

        double z;

        if (n < 3)

            return(0);

        for (i=0;i<n;i++) {

            j = (i + 1) % n;

            k = (i + 2) % n;

            z = (p[j].x - p[i].x) * (p[k].y - p[j].y);

            z -= (p[j].y - p[i].y) * (p[k].x - p[j].x);

            if (z < 0)

                flag |= 1;

            else if (z > 0)

                flag |= 2;

            if (flag == 3)

                return -1; //CONCAVE

            }

        if (flag != 0)

            return 1; //CONVEX

        else

        return 0;

    }

    12.Graham扫描法寻找凸包

    语法:Graham_scan(Point PointSet[],Point ch[],int n,int &len);

    参数:

    PointSet[] 输入的点集

    ch[] 输出的凸包上的点集,按照逆时针方向排列

    n PointSet中的点的数目

    len 输出的凸包上的点的个数

    返回值: null

    源程序:  

      struct Point{

        float x,y;

    }; 

    float multiply(Point p1,Point p2,Point p0)

    {

        return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y)); 

    }

    float distance(Point p1,Point p2)

    {

        return(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); 

    }

    void Graham_scan(Point PointSet[],Point ch[],int n,int &len)

    {

        int i,j,k=0,top=2;

        Point tmp;

       for(i=1;i<n;i++)

        if ((PointSet[i].y<PointSet[k].y)||((PointSet[i].y==PointSet[k].y)&&(PointSet[i].x<PointSet[k].x)))

        k=i;

        tmp=PointSet[0];

        PointSet[0]=PointSet[k];

        PointSet[k]=tmp; 

        for (i=1;i<n-1;i++)

            {

            k=i;

            for (j=i+1;j<n;j++)

                if ( (multiply(PointSet[j],PointSet[k],PointSet[0])>0) ||

                         ((multiply(PointSet[j],PointSet[k],PointSet[0])==0)

                             &&(distance(PointSet[0],PointSet[j])<distance(PointSet[0],PointSet[k])))   )

                    k=j;

            tmp=PointSet[i];

            PointSet[i]=PointSet[k];

            PointSet[k]=tmp;

            }

        ch[0]=PointSet[0];

        ch[1]=PointSet[1];

        ch[2]=PointSet[2]; 

        for (i=3;i<n;i++)

            {

            while (multiply(PointSet[i],ch[top],ch[top-1])>=0) top--;

            ch[++top]=PointSet[i];

            }

        len=top+1;

    }

    四、数论

    1.x的二进制长度

    语法:result=BitLength(int x);

    参数:

    x 测长的x

    返回值: x的二进制长度

    源程序:  

      int BitLength(int x)

    {

        int d = 0;

        while (x > 0) {

            x >>= 1;

            d++;

        }

        return d;

    }

    2.返回x的二进制表示中从低到高的第i

    语法:result=BitAt(int x, int i);

    参数:

    x 十进制 x

    i 要求二进制的第i

    返回值: 返回x的二进制表示中从低到高的第i

    注意:  

      最低位为第一位

    源程序:  

      int BitAt(int x, int i)

    {

        return ( x & (1 << (i-1)) );

    }

    3.模取幂运算

    语法:result=Modular_Expoent(int a,int b,int n);

    参数:

    a、b、n a^b mod n 的对应参数

    返回值: a^b mod n 的值

    注意:  

      需要BitLength和BitAt

    源程序:  

      int Modular_Expoent(int a,int b,int n)

    {

        int i, y=1;

        for (i = BitLength(b); i > 0; i--)

            { 

            y = (y*y)%n;

            if (BitAt(b,i) > 0) 

            y = (y*a)%n;

            }

        return y;

    }

    4.求解模线性方程

    语法:result=modular_equation(int a,int b,int n);

    参数:

    a、b、n ax=b (mod n) 的对应参数

    返回值: 方程的解

    源程序:  

      int ext_euclid(int a,int b,int &x,int &y)  //求gcd(a,b)=ax+by

    {

        int t,d;

        if (b==0) {x=1;y=0;return a;}

        d=ext_euclid(b,a %b,x,y);

        t=x;

        x=y;

        y=t-a/b*y;

        return d;

    }

    void modular_equation(int a,int b,int n)

    {

        int e,i,d;

        int x,y;

        d=ext_euclid(a,n,x,y);

        if (b%d>0)

           printf("No answer! ");

        else

            {

           e=(x*(b/d))%n;

            for (i=0;i<d;i++)

                printf("The %dth answer is : %ld ",i+1,(e+i*(n/d))%n); 

            }

    }

    5.求解模线性方程组(中国余数定理)

    语法:result=Modular_Expoent(int a,int b,int n);

    参数:

    B[]、W[] a=B[] (mod W[]) 的对应参数

    返回值: a 的值

    注意:  

      其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a

    源程序:  

      int ext_euclid(int a,int b,int &x,int &y)  //求gcd(a,b)=ax+by

    {

        int t,d;

        if (b==0) {x=1;y=0;return a;}

        d=ext_euclid(b,a %b,x,y);

        t=x;

        x=y;

        y=t-a/b*y;

        return d;

    }

    int China(int B[],int W[],int k)

    {

       int i;

        int d,x,y,a=0,m,n=1;

        for (i=0;i<k;i++)

            n*=W[i];

        for (i=0;i<k;i++)

           {

           m=n/W[i];

            d=ext_euclid(W[i],m,x,y);

            a=(a+y*m*B[i])%n;

            }

        if (a>0) return a;

        else return(a+n);

    }

    6.筛法素数产生器

    语法:result=prime(int a[],int n);

    参数:

    a[] 用于返回素数的数组

    n 产生n以内的素数,按升序放入a[]

    返回值: n以内素数的个数

    注意:  

      其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a

    源程序:  

      int prime(int a[],int n)

    {

        int i,j,k,x,num,*b;

        n++;

        n/=2;

        b=(int *)malloc(sizeof(int)*(n+1)*2);

        a[0]=2;a[1]=3;num=2;

        for(i=1;i<=2*n;i++)

            b[i]=0;

        for(i=3;i<=n;i+=3)

            for(j=0;j<2;j++)

                {

                x=2*(i+j)-1;

                while(b[x]==0)

                    {

                    a[num++]=x;

                    for(k=x;k<=2*n;k+=x)

                        b[k]=1;

                    }

                }

        return num;

    }

    7.判断一个数是否素数

    语法:result=comp(int n);

    参数:

    n 判断n是否素数

    返回值: 素数返回1,否则返回0

    源程序:  

      int comp(int n)

    {

       int i,flag=1;

        for (i=2;i<=sqrt(n);i++)

        if (n%i==0) {flag=0;break;}

        if (flag==1) return 1; else return 0;

    }

    五、图论

    1.Prim算法求最小生成树

    语法:prim(Graph G,int vcount,int father[]);

    参数:

    G 图,用邻接矩阵表示

    vcount 表示图的顶点个数

    father[] 用来记录每个节点的父节点

    返回值: null

    注意:  

      常数max_vertexes为图最大节点数

      常数infinity为无穷大

    源程序:  

      #define infinity 1000000

    #define max_vertexes 5 

    typedef int Graph[max_vertexes][max_vertexes];

    void prim(Graph G,int vcount,int father[])

    {

        int i,j,k;

        int lowcost[max_vertexes],closeset[max_vertexes],used[max_vertexes];

        for (i=0;i<vcount;i++)

            {

            lowcost[i]=G[0][i];

            closeset[i]=0; 

            used[i]=0;

            father[i]=-1; 

            }

        used[0]=1; 

        for (i=1;i<vcount;i++)

            {

            j=0;

            while (used[j]) j++;

            for (k=0;k<vcount;k++)

                if ((!used[k])&&(lowcost[k]<lowcost[j])) j=k;

            father[j]=closeset[j]; 

            used[j]=1;

            for (k=0;k<vcount;k++)

                if (!used[k]&&(G[j][k]<lowcost[k]))

                    { lowcost[k]=G[j][k];

                    closeset[k]=j; }

            }

    }

    2.Dijkstra算法求单源最短路径

    语法:result=Dijkstra(Graph G,int n,int s,int t, int path[]);

    参数:

    G 图,用邻接矩阵表示

    n 图的顶点个数

    s 开始节点

    t 目标节点

    path[] 用于返回由开始节点到目标节点的路径

    返回值: 最短路径长度

    注意:  

      输入的图的权必须非负

      顶点标号从0开始

      用如下方法打印路径:

        i=t;

        while (i!=s)

            {

            printf("%d<--",i+1);

            i=path[i];

            }

        printf("%d ",s+1); 

    源程序:  

      int Dijkstra(Graph G,int n,int s,int t, int path[])

    {

        int i,j,w,minc,d[max_vertexes],mark[max_vertexes];

        for (i=0;i<n;i++) mark[i]=0;

        for (i=0;i<n;i++)

            { d[i]=G[s][i];

            path[i]=s; }

        mark[s]=1;path[s]=0;d[s]=0;

        for (i=1;i<n;i++)

            {

           minc=infinity;

            w=0;

            for (j=0;j<n;j++)

                if ((mark[j]==0)&&(minc>=d[j])) {minc=d[j];w=j;}

            mark[w]=1;

            for (j=0;j<n;j++)

            if ((mark[j]==0)&&(G[w][j]!=infinity)&&(d[j]>d[w]+G[w][j]))

                { d[j]=d[w]+G[w][j];

                path[j]=w; }

            }

        return d[t];

    }

    3.Bellman-ford算法求单源最短路径

    语法:result=Bellman_ford(Graph G,int n,int s,int t,int path[],int success);

    参数:

    G 图,用邻接矩阵表示

    n 图的顶点个数

    s 开始节点

    t 目标节点

    path[] 用于返回由开始节点到目标节点的路径

    success 函数是否执行成功

    返回值: 最短路径长度

    注意:  

      输入的图的权可以为负,如果存在一个从源点可达的权为负的回路则success=0

      顶点标号从0开始

      用如下方法打印路径:

        i=t;

        while (i!=s)

            {

            printf("%d<--",i+1);

            i=path[i];

            }

        printf("%d ",s+1); 

    源程序:  

      int Bellman_ford(Graph G,int n,int s,int t,int path[],int success)

    {

        int i,j,k,d[max_vertexes];

        for (i=0;i<n;i++) {d[i]=infinity;path[i]=0;}

        d[s]=0;

        for (k=1;k<n;k++)

            for (i=0;i<n;i++)

                for (j=0;j<n;j++)

                    if (d[j]>d[i]+G[i][j]) {d[j]=d[i]+G[i][j];path[j]=i;}

        success=0;

        for (i=0;i<n;i++)

            for (j=0;j<n;j++)

                if (d[j]>d[i]+G[i][j]) return 0;

        success=1;

        return d[t];

    }

    4.Floyd-Warshall算法求每对节点间最短路径

    语法:Floyd_Washall(Graph G,int n,Graph D,Graph P);

    参数:

    G 图,用邻接矩阵表示

    n 图的顶点个数

    D D[i,j]表示从i到j的最短距离

    P P[i,j]表示从i到j的最短路径上j 的父节点 

    返回值: null

    源程序:  

      void Floyd_Washall(Graph G,int n,Graph D,Graph P)

    {

        int i,j,k;

        for (i=0;i<n;i++)

            for (j=0;j<n;j++)

                { D[i][j]=G[i][j];

                    P[i][j]=i; }

        for (i=0;i<n;i++) { D[i][i]=0;P[i][i]=0; }

        for (k=0;k<n;k++)

            for (i=0;i<n;i++)

                for (j=0;j<n;j++)

                    if (D[i][j]>D[i][k]+D[k][j])

                        { D[i][j]=D[i][k]+D[k][j];

                            P[i][j]=P[k][j]; }

    }

    六、排序/查找

    1.快速排序

    语法:quicksort(int l,int r,int b[]);

    参数:

    l 排序上界,开始时l=0

    r 排序下界,开始时r=数组元素个数

    b[] 被排序的元素

    返回值: null

    注意:  

      输出升序序列

    源程序:  

      void quicksort(int l,int r,int b[])

    {

        int i,j,x;

        if(l>=r) return;

        i=l;

        j=r;

        x=b[i];

        while(i!=j)

            {

            while(b[j]>x&&j>i) j--;

            if(i<j)

                {

                b[i]=b[j];

                i++;

                }

            while(b[i]<x&&j>i)i++;

                if(i<j)

                    {

                    b[j]=b[i];

                    j--;

                    }

            }

        b[i]=x;

        quicksort(l,j-1,b);

        quicksort(i+1,r,b);

    }

    2.希尔排序

    语法:shellsort(int a[],int n);

    参数:

    n 数组元素个数

    a[] 待排序数组

    返回值: null

    注意:  

      输出升序序列

    源程序:  

      void shellsort(int a[],int n)

    {

        int i,j,g;

        int temp,k;

        g=n/2;

        while(g!=0)

            {

            for(i=g+1;i<=n;i++)

                {

                temp=a[i];

                j=i-g;

                while(j>0)

                    {

                    k=j+g;

                    if(a[j]<=a[k])

                        j=0;

                    else

                        {

                        temp=a[j];a[j]=a[k];a[k]=temp;

                        }

                    j=j-g;

                    }

                }

            g=g/2;

            }

    }

    3.选择法排序

    语法:sort(int t[],int n);

    参数:

    t[] 待排序数组

    n 数组t[]元素的个数

    返回值: null

    注意:  

      输出升序序列

      小规模排序用

    源程序:  

      void sort(int t[],int n)

    {

       int i,j,k,temp;

        for (i=0;i<n;i++)

            {

            k=i;

            for (j=i;j<n;j++) if (t[j]<t[k]) k=j;

            temp=t[i];t[i]=t[k];t[k]=temp;

            }

    }

    4.二分查找

    语法:result=search_bin(int *t,int k);

    参数:

    t[] 待查找数组

    k 查找关键字

    返回值: 如果k在t[]中存在,输出i:t[i]=k,否则输出-1

    注意:  

      要求查找数组是有序升序序列

    源程序:  

      int search_bin(int *t,int k)

    {

        int low=1,high=10,mid;

        while (low<=high)

            {

            mid=(low+high)/2;

            if (k==t[mid]) return mid;

            else if (k<t[mid]) high=mid-1;

            else low=mid+1;

            }

        return -1;

    }

    七、数据结构

    1.顺序队列

    源程序:  

      #define maxsize 100

    typedef struct

    {

        int data[maxsize];

        int front;

        int rear;

    } sqqueue; 

    int sqinit(sqqueue *p) //队列初始化

    {

        p->front=0;

        p->rear=0;

        return 1;

    }

    int enqueue(sqqueue *q, int e) //入队

    {

        if((q->rear+1)%maxsize==q->front)

            return 0;

        else

            q->data[q->rear]=e;

        q->rear=(q->rear+1)%maxsize;

        return 1;

    }

    int dequeue(sqqueue *q) //出队

    {

        int e;

        if (q->front==q->rear)

            return 0;

        e=q->data[q->front];

        q->front=(q->front+1)%maxsize;

        return e;

    }

    int empty(sqqueue *q)  //判空

    {

        int v;

        if (q->front==q->rear)

            v=1;

        else

            v=0;

         return v; 

    }

    int gethead(sqqueue *q)  //取得头元素

    {

        int e;

        if (q->front==q->rear) 

            e=-1;

        else

            e=q->data[q->front];

        return e;

    }

    void display(sqqueue *q) //显示所有元素

    {

        int s;

        s=q->front;

        printf("the sequeue is display: ");

        if (q->front==q->rear)

            printf("the sequeue is empty!");

        else

            {

            while(s<q->rear)

                {

                printf("->%d", q->data[s]);

                s=(s+1)%maxsize;

                } 

        printf(" ");

    }

    }

    main(sqqueue *head)  //函数使用样例

    {

        int n,i,m,x,y,select,xq;

        printf("create a empty sequeue ");

        sqinit(head);

        printf("please input the sequeue length: "); 

        scanf("%d",&n);

        for (i=0;i<n;i++)

            {

            printf("please input a sequeue value: ");

            scanf("%d",&m);

            enqueue(head,m);

           }

        printf("head->rear:%d ",head->rear);

        printf("head->front:%d ",head->front);

        display(head);

        printf("select 1 **** enqueue()  ");

        printf("select 2 **** dequeue()  ");

        printf("select 3 **** empty ()  ");

        printf("select 4 **** gethead()  ");

        printf("select 5 **** display()  ");

        printf("please select (1--5):");

        scanf("%d",&select);

        switch(select)

            {

            case 1:

                { 

                printf("please input a value :  ");

                scanf("%d",&x);

                enqueue(head,x);

                display(head);

                break;

                }

            case 2:

                {

                dequeue(head);

                display(head);

                break;

                }

            case 3:

                {

            if(empty(head))

                printf("the sequeue is empty");

            else

                printf("the sequeue is full");

                }

            case 4:

                {

                y=gethead(head);

                printf("output head value:%d ",y);

                break;

                }

            case 5:

                {

                display(head);

                break;

                }

            }

        }

    2.顺序栈

    源程序:  

      #define m 100

    typedef struct

    {

        int stack[m];

        int top;

    } stackstru; 

    init(stackstru *s) /*装入栈*/

    {

        s->top=0;

        return 1;

    }

    int push(stackstru *s,int x) /*入栈操作*/

    {

        if (s->top==m)

            printf("the stack is overflow! ");

        else

            {

            s->top=s->top+1;

            s->stack[s->top]=x;

            }

    }

    void display(stackstru *s) /*显示栈所有数据*/

    {

        if(s->top==0)

            printf("the stack is empty! ");

        else

            {

            while(s->top!=0)

                {

                printf("%d->",s->stack[s->top]);

                s->top=s->top-1;

                }

            }

    }

    int pop(stackstru *s) /*出栈操作并返回被删除的那个记录*/

    {

        int y;

        if(s->top==0)

            printf("the stack is empty! ");

        else

            {

            y=s->stack[s->top];

            s->top=s->top-1;

            return y;

            }

    }

    int gettop(stackstru *s) /*得到栈顶数*/

        int e;

        if(s->top==0)

            return 0;

        else 

            e=s->stack[s->top];

        return e;

    }

    main(stackstru *p) //函数使用演示

    {

        int n,i,k,h,x1,x2,select;

        printf("create a empty stack! ");

        init(p);

        printf("input a stack length: ");

        scanf("%d",&n);

        for(i=0;i<n;i++)

            {

            printf("input a stack value: ");

            scanf("%d",&k);

            push(p,k);

            }

        printf("select 1:display() ");

        printf("select 2:push() ");

        printf("select 3:pop() ");

        printf("select 4:gettop() ");

        printf("input a your select(1-4): ");

        scanf("%d",&select);

        switch(select)

            {

            case 1:

                {

                display(p);

                break;

                }

            case 2:

                {

                printf("input a push a value: ");

                scanf("%d",&h);

                push(p,h);

                display(p);

                break;

                }

            case 3:

                {

                x1=pop(p);

                printf("x1->%d ",x1);

                display(p);

                break;

                }

            case 4:

                {

                x2=gettop(p);

                printf("x2->%d",x2);

                break;

                }

            }

    }

    3.链表

    源程序:  

      # define null 0 

    typedef char ElemType; /* 字符型数据*/ 

    typedef struct LNode

    {

        ElemType data;

        struct LNode *next;

    };

    setnull(struct LNode **p);

    int length (struct LNode **p);

    ElemType get(struct LNode **p,int i);

    void insert(struct LNode **p,ElemType x,int i);

    int delete(struct LNode **p,int i);

    void display(struct LNode **p); 

    main()

    {

        struct LNode *head,*q; /*定义静态变量*/

        int select,x1,x2,x3,x4;

        int i,n; 

        int m,g;

        char e,y; 

        head=setnull(&head); /*建议链表并设置为空表*/

        printf("请输入数据长度: ");

        scanf("%d",&n);

        for(i=1;i<n;i++);

            {

            printf("将数据插入到单链表中: ");

            scanf("%d",&y);

            insert(&head,y,i);} /*插入数据到链表*/

            display(&head); /*显示链表所有数据*/

            printf("select 1 求长度 length() ");

            printf("select 2 取结点 get() ");

            printf("select 3 求值查找 locate() ");

            printf("select 4 删除结点 delete() ");

            printf("input your select: ");

            scanf("%d",&select); 

            switch(select)

                {

                case 1:

                    {

                    x1=length(&head);

                    printf("输出单链表的长度%d ",x1);

                    display(&head);

                    }break;

                case 2:

                    {

                    printf("请输入要取得结点: ");

                    scanf("%d",&m);

                    x2=get(&head,m);

                    printf(x2);

                    display(&head);

                    }break;

             case 3:

                    {

                    printf("请输入要查找的数据: ");

                    scanf("%d",&e);

                    x3=locate(&head,e);

                    printf(x3);

                    display(&head);

                    }break;

             case 4:

                    {

                    printf("请输入要删除的结点: ");

                    scanf("%d",&g);

                    x4=delete(&head,g);

                    printf(x4);

                    display(&head);

                    }break;

                }

            }

    }

    setnull(struct LNode **p)

    {

        *p=null;

    }

    int length (struct LNode **p)

    {

        int n=0;

        struct LNode *q=*p;

        while (q!=null)

            {

            n++;

            q=q->next;

            }

        return(n);

    }

    ElemType get(struct LNode **p,int i)

    {

        int j=1;

        struct LNode *q=*p;

        while (j<i&&q!=null)

            {

            q=q->next;

            j++;

            }

            if(q!=null)

                return(q->data);

            else

                printf("位置参数不正确! ");

    }

    int locate(struct LNode **p,ElemType x)

        {

        int n=0;

        struct LNode *q=*p;

        while (q!=null&&q->data!=x)

            {

            q=q->next;

            n++;

            }

        if(q==null)

            return(-1);

        else

            return(n+1);

    }

    void insert(struct LNode **p,ElemType x,int i)

        {

        int j=1;

        struct LNode *s,*q;

        s=(struct LNode *)malloc(sizeof(struct LNode));

        s->data=x;

        q=*p;

        if(i==1)

            {

            s->next=q;

            p=s;

            }

        else

            {

            while(j<i-1&&q->next!=null)

                {

                q=q->next;

                j++;

                }

            if(j==i-1)

                {

                s->next=q->next;

                q->next=s;

                }

            else 

                printf("位置参数不正确! ");

            } 

    }

    int delete(struct LNode **p,int i)

    {

        int j=1;

        struct LNode *q=*p,*t;

        if(i==1)

            {

            t=q;

            *p=q->next;

            }

        else

            {

            while(j<i-1&&q->next!=null)

                {

                q=q->next;

                j++;

                }

            if(q->next!=null&&j==i-1)

                {

                t=q->next;

                q->next=t->next;

                }

            else 

                printf("位置参数不正确! ");

            }

        if(t=null) 

        free(t);

    }

    void display(struct LNode **p)

        { 

        struct LNode *q;

        q=*p;

        printf("单链表显示: ");

        if(q==null)

            printf("链表为空!");

        else if (q->next==null)

            printf("%c ",q->data);

        else

            {

            while(q->next!=null)

                {

                printf("%c->",q->data);

                q=q->next;

                }

            printf("%c",q->data);

        }

        printf(" ");

    }

    4.链栈

    源程序:  

      # define null 0 

    typedef struct stacknode

    {

        int data;

        struct stacknode *next;

    } stacklink;

    typedef struct

    {

        stacklink *top;

        int stacksize;

        }stackk;

    initlink(stackk *s)

    {

       s->top=(stacklink *)malloc(sizeof(stacklink));

        s->top->data=0;

        s->top->next=null;

    int poplink(stackk *s)

    {

       stackk *p;int v;

        if(s->top->next==null) printf("the stackis empty ");

        else

            {

            v=s->top->next->data;

             p=s->top->next;

             s->top=s->top->next;

            } 

        free(p);

        return v;

    }

    int pushlink(stackk *s,int x)

    {

       stackk *p;

        p=(stacklink *)malloc(sizeof(stacklink));

        p->data=x;

        p->next=s->top->next;

        s->top->next=p;

    }

    int gettop(stackk *s)

    {

       int e;

        if(s==null) printf("the stack is empty! ");

        e=s->top->next->data;

        return e;

    }

    display(stackk *s)

    {

       stackk *p;

        p=s->top->next;

        printf("display the stacklink: ");

        if (s->top=null) printf("the stacklink is empty! ");

        else

           {

           while(p)

                {

               printf("->%d",p->data);

                p=p->next;

               }

            }

    }

    main(stacklink *p)

    {

       int n,k,i,select,h,x1,x2;

        printf("create a empty stacklink! ");

        initlink(p);

        printf("input a stacklink length: ");

        scanf("%d",&n);

        for (i=1;i<=n;i++)

            {printf("input a stacklink value: ");

        scanf("%d",&k);

        pushlink(p,k);

            }

        printf("select 1:display() ");

        printf("select 2:pushlink() ");

        printf("select 3:poplink() ");

        printf("select 4:gettop() ");

        printf("input a your select(1-4): ");

        scanf("%d",&select);

        switch(select)

            {case 1:

                 {display(p);break;}

            case 2:

               {printf("input a push a value : ");

                scanf("%d",&h);

                pushlink(p,h);

                display(p);

                break;}

            case 3:

               {x1=poplink(p);printf("x1->%d ",x1);

                display(p);

                break;}

            case 4:

               {x2=gettop(p);printf("x2->%d",x2);

                break;}

            }

    }

    5.二叉树

    源程序:  

      typedef struct bitnode

    {

        char data;

        struct bitnode *lchild, *rchild;

    }bitnode, *bitree; 

    void createbitree(t,n)

    bitnode ** t;

    int *n;

    {

        char x;

        bitnode *q;

        *n=*n+1;

        printf("  Input %d DATA:",*n);

        x=getchar();

        if(x!=' ') getchar();

        if (x==' ')

            return;

        q=(bitnode*)malloc(sizeof(bitnode));

        q->data=x;

        q->lchild=NULL;

        q->rchild=NULL;

        *t=q;

        printf(" This Address is: %o, Data is: %c,  Left Pointer is: %o, Right Pointer is: %o",q,q->data,q->lchild,q->rchild);

        createbitree(&q->lchild,n);

        createbitree(&q->rchild,n);

        return;

    }

    void visit(e)

    bitnode *e;

    {

        printf(" Address: %o, Data: %c, Left Pointer: %o, Right Pointer: %o ",e,e->data,e->lchild,e->rchild);

    }

    void preordertraverse(t)

    bitnode *t;

    {

        if(t)

            {

            visit(t);

            preordertraverse(t->lchild);

            preordertraverse(t->rchild);

            return ;

            }

       else

         return ;

    }

    void countleaf(t,c)

    bitnode *t;

    int *c;

    {

        if(t!=NULL)

            {

            if (t->lchild==NULL && t->rchild==NULL)

            {*c=*c+1;

            }

        countleaf(t->lchild,c);

        countleaf(t->rchild,c);

    }

    return;

    }

    int treehigh(t)

    bitnode *t;

    {

       int lh,rh,h;

        if(t==NULL)

            h=0;

        else

           {

            lh=treehigh(t->lchild);

            rh=treehigh(t->rchild);

            h=(lh>rh ? lh:rh)+1;

            }

        return h;

    }

    main()

    {

        bitnode *t; int count=0;

        int n=0;

       printf("  Please input TREE Data: ");

        createbitree(&t,&n);

       printf("  This is TREE struct:  ");

        preordertraverse(t);

       countleaf(t,&count);

        printf("  This TREE has %d leaves ",count);

       printf(" , High of The TREE is: %d ",treehigh(t));

    }

    整数划分就是将一个正整数表示成一系列正整数之和,问有多少种不同划分方案!

             例如整数6可以划分成一下11中方案:

            6

            5 + 1

            4 + 2, 4 + 1 + 1

            3 + 3, 3 + 2 + 1, 3 + 1 + 1 + 1

            2 + 2 + 2, 2 + 2 + 1 + 1, 2 + 1 + 1 + 1 + 1

            1 + 1 + 1 + 1 + 1 + 1 

           如果你是编程好手看到这样的排列,可能一下子就能想到一种解题思路了!感慨,算法就是在培养解决问题的思路!!言归正传!先介绍下书上的思路:

                         一、p(n,m)含义:在正整数n的所有不同划分中,最大加数不大于m的划分数(m<=n;m,n>=1)!求整数6有几种划分时,既求p(6,6)。。。

                         二、函数递归关系:

    1、n<1||m<1,return 0

    2、n==1||m==1,p(n,m)=1

    3、n<m,p(n,m)=p(n,n);例如:p(6,10)=p(6,6)   

    4、n>m,p(n,m)=p(n,m-1)+p(n-m,m);例如:p(6,5)=p(6,4)+p(2,4); p(6,2)=p(6,1)+p(4,2);(这个等式是关键)

    代码如下

    #include<cstdio>

    int q(int n,int m)

    {

        if((n<1)||(m<1)) return 0;

        if(n==1||m==1) return 1;

        if(n<m) return q(n,n);

        if(n==m) return q(n,m-1)+1;

        return q(n,m-1)+q(n-m,m);

    }

    int main()

    {

        printf("%d ", q(6,6));

        return 0;

    }

    未完待续,,,

     

     

     

     

  • 相关阅读:
    leetcode Remove Linked List Elements
    leetcode Word Pattern
    leetcode Isomorphic Strings
    leetcode Valid Parentheses
    leetcode Remove Nth Node From End of List
    leetcode Contains Duplicate II
    leetcode Rectangle Area
    leetcode Length of Last Word
    leetcode Valid Sudoku
    leetcode Reverse Bits
  • 原文地址:https://www.cnblogs.com/jeff-wgc/p/4483366.html
Copyright © 2011-2022 走看看