c语言学习之代码

来源:互联网 发布:淘宝开店注册网址 编辑:程序博客网 时间:2024/05/17 22:58

1、贪心算法

//贪心算法装箱问题#include<stdio.h>#include<stdlib.h>#define V 100//物品体积typedef struct{int gno;//物品编号int gv;//物品体积}ELE;//物品结点typedef struct goods{int vno;struct goods * link;}GOODS;//箱子结点typedef struct box{int remainder;//剩余体积GOODS * hg;struct box * next;}BOX;void printELE(ELE * head,int n){int i;for(i=0;i<n;i++)printf("%d,%d\n",head[i].gno,head[i].gv);}void printBOX(BOX * head){BOX * p=head;int i=1;while(p){printf("\n第%d个箱子剩余%d\t",i++,p->remainder);while(p->hg){printf("这个箱子装了%d\t",p->hg->vno);p->hg=p->hg->link;}p=p->next;}}//降序排序void sortD(ELE * g,int n){int i;int j;ELE t;for(i=0;i<n-1;i++)for(j=0;j<n-i;j++)if(g[j].gv<g[j+1].gv){t=g[j];g[j]=g[j+1];g[j+1]=t;}}//装箱BOX * process(ELE * g,int n){int i;BOX * h=NULL,* t,* p,* k;GOODS * q,* m;for(i=0;i<n;i++){q=(GOODS *)malloc(sizeof(GOODS));//先给物品分配q->vno=g[i].gno;q->link=NULL;for(k=h;k&&k->remainder<g[i].gv;k=k->next);//没开箱子的情况,即K为NULL,或者找出能放下的第一个箱子if(!k)//这里是一个箱子都没开{p=(BOX *)malloc(sizeof(BOX));//开箱p->remainder=V;p->next=NULL;if(!h)//是不是第一个箱子h=t=p;elset=t->next=p;//不是直接挂,t指向最后一个箱子t->next=NULL;p->hg=q;p->remainder=V-g[i].gv;//放入物品}else//这个是有箱子,并且能放下{for(m=k->hg;m->link;m=m->link);m->link=q;k->remainder-=g[i].gv;}}return h;}int main(void){ELE * g=NULL;BOX * b=NULL;int i;int n;printf("请输入物品个数:\n");scanf("%d",&n);g=(ELE *)malloc(n*sizeof(ELE));//输入物品数据for(i=0;i<n;i++){g[i].gno=i+1;printf("请输入第%d个物品的体积:",i+1);scanf("%d",&g[i].gv);}printELE(g,n);sortD(g,n);printELE(g,n);b=process(g,n);printBOX(b);}

2、哈弗曼编码

//哈夫曼编码,利用结构体数组存储哈夫曼树//用另一个结构体存储编码#include<stdio.h>#include<stdlib.h>#define N 10typedef struct{char word;//存储字符int weight;int left,right,parent;}HuffNode;typedef struct{int code[N];int start;}HuffCode;void CreatHuffManTree(HuffNode * hn,int n){int i;int j;int k1;int k2;for(i=0;i<n-1;i++){k1=k2=-1;for(j=0;j<n+i;j++){if(hn[j].parent==-1&&k1==-1)k1=j;else if(hn[j].parent==-1){k2=j;break;}for(;j<n+i;j++)if(hn[j].parent==-1)if(hn[j].weight<hn[k1].weight){k2=k1;k1=j;}else if(hn[j].weight<hn[k2].weight)k2=j;hn[n+i].weight=hn[k1].weight+hn[k2].weight;hn[n+i].parent=-1;hn[n+i].left=k1;hn[n+i].right=k2;hn[k1].parent=hn[k2].parent=n+i;}}}void CreatHuffManCode(HuffNode * hn,int n,HuffCode * hc){int i;int c;int p;for(i=0;i<n;i++){c=i;p=hn[c].parent;hc[i].start=N;while(p!=-1){if(hn[p].left==c)hc[i].code[--hc[i].start]=0;elsehc[i].code[--hc[i].start]=1;c=p;p=hn[c].parent;}}}void printHuffManCode(HuffNode * hn,int n,HuffCode * hc){int i;int j;for(i=0;i<n;i++){printf("%c的编码是:",hn[i].word);for(j=hc[i].start;j<N;j++)printf("%2d",hc[i].code[j]);printf("\n");}}int main(void){int i;char c;int w;int leafcount;HuffNode * hn;HuffCode * hc;printf("请输入叶子个数:");scanf("%d",&leafcount);hn=(HuffNode *)malloc((2*leafcount-1)*sizeof(HuffNode));for(i=0;i<leafcount;i++){printf("请输入第%d个叶子的信息:\n权值 字符 ",i+1);scanf("%d %c",&w,&c);//先输字符回车被误判//printf("权值:");//scanf("%d",&w);hn[i].word=c;hn[i].weight=w;hn[i].left=hn[i].right=hn[i].parent=-1;}CreatHuffManTree(hn,leafcount);hc=(HuffCode *)malloc(leafcount*sizeof(HuffCode));CreatHuffManCode(hn,leafcount,hc);printHuffManCode(hn,leafcount,hc);}

3、八皇后

//八皇后#include<stdio.h>int a[8]={0};//存储第几列能不能放皇后int b[15]={0};//存储左上右下方向能不能放皇后int c[15]={0};//存储左下右上方向能不能放皇后int x[8]={0};//存储第几行的皇后放在第几个void print(void){int i;int j;for(i=0;i<8;i++){for(j=0;j<8;j++){if(x[i]==j)printf("Q");elseprintf("*");}printf("\n");}}void chess(int i){int j;for(j=0;j<8;j++){if(a[j]==0 && b[i+j]==0 && c[i-j+7]==0){a[j]=b[i+j]=c[i-j+7]=1;x[i]=j;if(i<7)chess(i+1);else{print();printf("\n");}a[j]=b[i+j]=c[i-j+7]=0;x[i]=0;}}}int main(void){chess(0);return 0;}

4、判断左右括号匹配

//判断一个表达式的左右括号数目是否匹配#include<stdio.h>#include<string.h>void main(void){char exp[100];int top=-1,i;printf("请输入一个表达式:\n");gets(exp);for(i=0;exp[i]!=0;i++){if(exp[i]=='(')top++;else if(exp[i]==')')if(top>=0)top--;else{top--;break;}}if(top==-1)printf("匹配!");elseprintf("不匹配!");}

5、双向链表

//2013_2_26不带头结点的双向链表#include<stdio.h>#include<malloc.h>#include<stdlib.h>typedef struct node{int data;struct node *pp,*fp;}ElemPSN;//创建双向链表ElemPSN *CreateDlink(int a[],int n){ElemPSN *head,*tail,*p;int i;//head是头结点指针,tail作为尾指针head=tail=p=NULL;for(i=0;i<n;++i){p=(ElemPSN *)malloc(sizeof(ElemPSN));p->data=a[i];p->pp=p->fp=NULL;if(i==0)//判断是否为第一个结点head=tail=p;else{tail->pp=p;p->fp=tail;tail=p;}}return head;}//正向输出该链表的数据域的值void Aprintlink(ElemPSN *head){ElemPSN *p;for(p=head;p;p=p->pp)printf("%5d",p->data);}//逆向输出该链表的数据域的值void Bprintlink(ElemPSN *head){ElemPSN *p;for(p=head;p->pp;p=p->pp);//两个for循环的终止条件不同for(;p;p=p->fp)printf("%5d",p->data);}//删除双向链表中值为val的结点//假设没有重复值//不需要两个指针联动,分头删、尾删、中间删ElemPSN *DelNode(ElemPSN *head,int val)//需要有返回值,否则有可能删掉head{ElemPSN *p,*q,*s;//s,q分别作为p的前驱结点和后继结点for(p=head;p&&p->data!=val;p=p->pp);//寻找值为val的结点if(!p)printf("没有找到值为val的结点。\n");else{q=p->pp;s=p->fp;if(p==head)//分为三种情况{q->fp=s;head=q;}else if(p->pp==NULL)s->pp=q;else{s->pp=q;q->fp=s;}free(p);}return head;}//主函数int main(void){int a[]={10,20,30,40,50};int val;ElemPSN *head,*p;//创建双向链表head=CreateDlink(a,5);//正向输出Aprintlink(head);printf("\n");//逆向输出Bprintlink(head);printf("\n");//删除值为val的结点printf("请输入要删的值val:");scanf("%d",&val);head=DelNode(head,val);//正向输出Aprintlink(head);printf("\n");}

6、单向循环链表

//创建单向循环链表以及实现插入和删除#include<stdio.h>#include<malloc.h>#include<stdlib.h>typedef struct Node{int data;struct Node *next;}ElemSN;//单向循环链标的创建ElemSN * CreateLink(int a[],int n){ElemSN * head, * p,* tail;int i;for(i=0;i<n;++i){p=(ElemSN *)malloc(sizeof(ElemSN));p->data=a[i];if(i==0)head=tail=p;elsetail=tail->next=p;tail->next=head;}return head;}//输出单项循环链表PrintLink(ElemSN * head){ElemSN * p=head;printf("单向循环链表的值为:\n");do{printf("%5d",p->data);p=p->next;}while(p!=head);}//删除值为val的结点,假设无重复值ElemSN * DelNode(ElemSN * head,int val){ElemSN * p=head,* q=NULL;do{if(p->data==val)break;q=p;p=p->next;}while(p-head);//也可以以q作为判断条件/*可替换if为下if(p==head&&q!=NULL)printf("没有找到要删除的值!\n");else{if(q==NULL){for(q=p;q->next!=head;q=q->next);head=p->next;}q->next=p->next;free(p);}*/if(p!=head){q->next=p->next;free(p);}else if(q==NULL){for(q=p;q->next!=head;q=q->next);q->next=p->next;head=p->next;free(p);}elseprintf("没有找到要删除的值!\n");return head;}//插入新结点s,假设有序ElemSN * InsertNode(ElemSN * head,ElemSN * s){ElemSN * p=head,* q=NULL;do{if(p->data>s->data)break;q=p;p=p->next;}while(p-head);if(q==NULL){for(q=p;q->next!=p;q=q->next);head=s;}s->next=p;q->next=s;return head;}//主函数int main(void){ElemSN * head,* s;ElemSN x;int a[6]={10,20,30,40,50,60};int val,insert;head=CreateLink(a,6);PrintLink(head);printf("\n");printf("请输入要删除的值:\n");scanf("%d",&val);head=DelNode(head,val);PrintLink(head);printf("\n");printf("请输入要插入的值:\n");scanf("%d",&insert);s=(ElemSN *)malloc(sizeof(ElemSN));s->data=insert;//s=&x;//x.data=insert;head=InsertNode(head,s);PrintLink(head);printf("\n");}

7、万年历

//已知1900年1月1号是礼拜一,任意输入年月,打印出该月的日历#include<stdio.h>void main(void){int i=1900,sum=1,k;//sum最终表示这月第一天是星期几,k表示这月有几天int year,month;printf("请输入大于1900年的年份:\n");scanf("%d",&year);printf("请输入月份:\n");scanf("%d",&month);for(;i<year;i++){if((i%4==0&&i%100!=0)||i%400==0)//判断是润年sum+=366;elsesum+=365;}switch(month){case 12 :sum+=30;case 11 :sum+=31;case 10 :sum+=30;case 9 :sum+=31;case 8 :sum+=31;case 7 :sum+=30;case 6 :sum+=31;case 5 :sum+=30;case 4 :sum+=31;case 3 :if((i%4==0&&i%100!=0)||i%400==0)//判断是润年sum+=29;elsesum+=28;case 2 :sum+=31;}sum=(sum-1)%7+1;//+1算出这月第一天是礼拜几,第一列从礼拜天开始,因此第一天是礼拜几,就得打几次tabprintf("\n\t\t\t\t%d年%d月\t\t\t\t\n\n",year,month);printf("\t日\t一\t二\t三\t四\t五\t六\t\n");if(sum!=7)for(i=0;i<sum;i++)printf("\t");if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)k=31;else if(month==2){if((i%4==0&&i%100!=0)||i%400==0)//判断是润年k=29;elsek=28;}elsek=30;for(i=1;i<=k;i++){printf("\t%d",i);if((sum+i)%7==0)printf("\n\n");}printf("\n");}

8、约瑟夫环

#include<stdio.h>#define N 100void main(){int a[N],m,n,k=0,j,i;printf("请输入人数n:\n");scanf("%d",&n);printf("请输入正整数m:\n");scanf("%d",&m);printf("请输入各个人的密码:\n");for(i=0;i<n;i++)scanf("%d",&a[i]);printf("出列顺序为:");for(i=0;i<n;i++){j=1;while(j<m){while(a[k]==0)k=(k+1)%n;j++;k=(k+1)%n;}while(a[k]==0)k=(k+1)%n;printf("%4d",k+1);m=a[k];a[k]=0;}}

9、递归

//一些简单的递归的调用#include<stdio.h>int jiecheng1(int n){int m=1;n&&(m=n*jiecheng1(n-1));return m;}int jiecheng2(int n){if(n==0)return 1;elsereturn n*jiecheng2(n-1);}void erjinzhi1(int n){if(n!=0)erjinzhi1(n/2);printf("%2d",n%2);}int lianjia(int n){int m=0;n&&(m=n+lianjia(n-1));return m;}void nizhi(int n){if(n!=0){printf("%2d",n%10);n=n/10;nizhi(n);}}int weihe(int n){int m=0;if(n!=0)m=n%10+weihe(n/10);return m;}int weimax(int n){int m=0;if(n!=0){m=((m<=(n%10)?(n%10):weimax(n/10)));}return m;}int weishu(int n){int m=0;if(n!=0)m=weishu(n/10)+1;return m;}void print(int a[],int n){if(n!=0){printf("%5d",a[0]);print(a+1,n-1);}}void fanprint(int a[],int n){if(n!=0){fanprint(a+1,n-1);printf("%5d",a[0]);}}int arraysum(int a[],int n){if(n==1)return a[0];elsereturn a[0]+arraysum(a+1,n-1);}void main(void){int n=4;int m=543210;int a[10]={1,2,3,4,5,6,7,8,9,0};printf("%d的阶乘是%d,%d!\n",n,jiecheng1(n),jiecheng2(n));printf("%d的二进制是:",n);erjinzhi1(n);printf("\n%d的连加是%d!\n",n,lianjia(n));printf("%d的逆置是:",m);nizhi(m);printf("\n%d的各个位之和是:%d\n",m,weihe(m));printf("%d的位数是:%d\n",m,weishu(m));printf("数组a的正向逆向输出是:\n");print(a,10);printf("\n");fanprint(a,10);printf("\n数组a的和是:%d\n",arraysum(a,10));}

10、逆波兰表达式

//逆波兰表达式实现表达式的计算#include<stdio.h>#include<string.h>int opl(char ch) //运算符的优先级判断{int op;switch (ch){case '*' :case '/' : op=4;break;case '+' :case '-' : op=3;break;case '(' : op=2;break;case '@' : op=1;}return op;}long process(long x1,long x2,char ch) //将字符运算符应用成算术运算符{long op;switch (ch){case '*' : op=x2*x1;break;case '/' : op=x2/x1;break;case '+' : op=x2+x1;break; case '-' : op=x2-x1;break;}return op;}void exchange(char pm[],char pa[]) //将中缀表达式转化为后缀表达式(逆波兰表达式){char stack[10];int top=-1;stack[++top]='@';while(*pm){if(*pm=='('){stack[++top]='(';pm++;}else if(*pm>='0'&&*pm<='9'){(*pa)=(*pm);pm++;pa++;}else if(*pm=='+'||*pm=='-'||*pm=='*'||*pm=='/'){while(opl(*pm)<=opl(stack[top]))//栈外运算符优先级>栈顶运算符优先级,直接入//反之,<=则先出,出完再入*(pa++)=stack[top--];stack[++top]=*(pm++);*(pa++)=' ';}else if(*pm==')'){while(stack[top]!='(')*(pa++)=stack[top--];top--;pm++;}elsepm++;}while(stack[top]!='@'){*(pa++)=stack[top--];}*pa=0; //给pa一个结束标志,注意不是赋值'0'}long complete(char a[])//对后缀表达式进行计算{long x1,x2,y,top=-1;long stack[30];while(*a){if(*a==' ')a++;else if(*a>='0'&&*a<='9'){y=0;while(*a>='0'&&*a<='9'){y=y*10+*a-'0'; //将字符转化为数字a++;}stack[++top]=y;}else if(*a=='+'||*a=='-'||*a=='*'||*a=='/'){x1=stack[top--];x2=stack[top--]; // 注意区分x1,x2的顺序stack[++top]=process(x1,x2,*a);a++;}}if(top==0)return stack[top];elsereturn 0;}//判断括号匹配int pipei(char exp[]){int i,top=-1;for(i=0;exp[i]!=0;i++){if(exp[i]=='(')top++;else if(exp[i]==')')if(top>=0)top--;else{top--;break;}}if(top==-1)return 1;elsereturn 0;}//主函数void main(void){char m[100],a[100];long record=0;printf("请输入一个表达式:\n");gets(m);if(pipei(m)){exchange(m,a);printf("后缀表达式为:%s!\n",a);record=complete(a);printf("这个表达式的值是%ld!\n",record);}elseprintf("左右括号不匹配,无法计算!\n");}









0 0