发布时间:2025-06-24 17:36:03  作者:北方职教升学中心  阅读量:185



文章末尾为 2023-2024 春学期上机考试题目。

又是睿智OJ,有的题严格判空格和换行符,有的题又不判;有的题必须用 fgets 读入换行符,有的题又不能读入换行符;突出一个逆天。

第二章 线性表

1 顺序表的插入运算

#include<stdio.h>#include<stdlib.h>typedefstructnode{intval;structnode*next;}Node,List;List *init(void){List *s =(List*)malloc(sizeof(List));Node *tail =s;intn;s->next =NULL,s->val =-1;scanf("%d",&n);for(inti =0;i <n;++i){Node *node =(Node*)malloc(sizeof(Node));scanf("%d",&node->val);node->next =NULL,tail->next =node,tail =node;}returns;}voidinsert(List *s){Node *node =(Node*)malloc(sizeof(Node)),*curr =s;scanf("%d",&node->val);while(curr->next){if(node->val >curr->next->val)curr =curr->next;elsebreak;}node->next =curr->next,curr->next =node;}voidtraverse(List *s){for(Node *curr =s->next;curr;curr =curr->next)printf("%d ",curr->val);printf("n");}intmain(){List *s =init();insert(s);traverse(s);return0;}

2 线性表的就地逆置

#include<stdio.h>#include<stdlib.h>intarr[1005]={};typedefstructnode{intval;structnode*next;}Node,List;List *init(intn){List *s =(List*)malloc(sizeof(List));Node *tail =s;s->next =NULL,s->val =-1;for(inti =0;i <n;++i){Node *node =(Node*)malloc(sizeof(Node));scanf("%d",&arr[i]);node->val =arr[i],node->next =NULL;tail->next =node,tail =node;}returns;}voidreverse(List *s,intn){// 三指针迭代Node *prev =NULL,*curr =s->next;while(curr){Node *next =curr->next;curr->next =prev;prev =curr,curr =next;}s->next =prev;intbegin =0,end =n -1;while(begin <end){inttmp =arr[begin];arr[begin]=arr[end],arr[end]=tmp;++begin,--end;}}voidtraverse(List *s,intn){// 会尾判空格for(Node *curr =s->next;curr;curr =curr->next){if(!curr->next)printf("%d",curr->val);elseprintf("%d ",curr->val);}printf("\n");for(inti =0;i <n;++i){if(i ==n -1)printf("%d",arr[i]);elseprintf("%d ",arr[i]);}printf("\n");}intmain(){intn;scanf("%d",&n);List *s =init(n);reverse(s,n);traverse(s,n);return0;}

3 顺序表的删除

#include<stdio.h>#include<stdlib.h>intn,m1,m2;intarr1[1005]={};intarr2[1005]={};typedefstructnode{intval;structnode*next;}Node,List;List *init(void){scanf("%d %d %d",&n,&m1,&m2);List *s =(List*)malloc(sizeof(List));Node *tail =s;s->next =NULL,s->val =-1;for(inti =0;i <n;++i){Node *node =(Node*)malloc(sizeof(Node));scanf("%d",&node->val);node->next =NULL,tail->next =node,tail =node;}for(inti =0;i <m1;++i)scanf("%d",&arr1[i]);for(inti =0;i <m2;++i)scanf("%d",&arr2[i]);returns;}voiddelete(List *s){// 三指针遍历inth1 =0,h2 =0;Node *curr =s->next;while(h1 <m1 &&h2 <m2){if(arr1[h1]<arr2[h2])++h1;elseif(arr1[h1]>arr2[h2])++h2;else{intval =arr1[h1];while(curr->next){if(curr->next->val ==val){Node*tmp =curr->next;curr->next =tmp->next;free(tmp);}elseif(curr->next->val <val)curr =curr->next;elsebreak;}++h1,++h2;}}}voidtraverse(List *s){for(Node *curr =s->next;curr;curr =curr->next)printf("%d ",curr->val);printf("n");}intmain(){List *s =init();delete(s);traverse(s);return0;}

4 单链表的归并

#include<stdio.h>#include<stdlib.h>typedefstructnode{intval;structnode*next;}Node,List;List *init(intn){List *s =(List*)malloc(sizeof(List));Node *tail =s;s->next =NULL,s->val =-1;for(inti =0;i <n;++i){Node *node =(Node*)malloc(sizeof(Node));scanf("%d",&node->val);node->next =NULL,tail->next =node,tail =node;}returns;}List*merge(List*src1,List*src2){if(!src1->next)returnsrc2;if(!src2->next)returnsrc1;List*dest =(List*)malloc(sizeof(List));dest->next =NULL,dest->val =-1;Node *curr1 =src1->next,*curr2 =src2->next,*head =dest,*tmp =NULL;// 头插逆序, 尾插正序, 以下采用头插法while(curr1 &&curr2){if(curr1->val <curr2->val){tmp =curr1->next,curr1->next =head->next;head->next =curr1,curr1 =tmp;}else{tmp =curr2->next,curr2->next =head->next;head->next =curr2,curr2 =tmp;}}while(curr1){tmp =curr1->next,curr1->next =head->next;head->next =curr1,curr1 =tmp;}while(curr2){tmp =curr2->next,curr2->next =head->next;head->next =curr2,curr2 =tmp;}src1->next =NULL,src2->next =NULL;returndest;}voidtraverse(List *s){for(Node *curr =s->next;curr;curr =curr->next)printf("%d ",curr->val);printf("n");}intmain(){intn,m;scanf("%d %d",&n,&m);List *s1 =init(n);List *s2 =init(m);List *s =merge(s1,s2);traverse(s);return0;}

5 单链表的删除

#include<stdio.h>#include<stdlib.h>typedefstructnode{intval;structnode*next;}Node,List;List *init(intn){List *s =(List*)malloc(sizeof(List));Node *tail =s;s->next =NULL,s->val =-1;for(inti =0;i <n;++i){Node *node =(Node*)malloc(sizeof(Node));scanf("%d",&node->val);node->next =NULL,tail->next =node,tail =node;}returns;}voiddelete(List *s,List *s1,List *s2){// 三指针遍历Node *h =s->next,*h1 =s1->next,*h2 =s2->next;while(h1->next &&h2->next){if(h1->val <h2->val)h1 =h1->next;elseif(h1->val >h2->val)h2 =h2->next;else{intval =h1->val;while(h->next){if(h->next->val ==val){Node*tmp =h->next;h->next =tmp->next;free(tmp);}elseif(h->next->val <val)h =h->next;elsebreak;}h1 =h1->next,h2 =h2->next;}}}voidtraverse(List *s){for(Node *curr =s->next;curr;curr =curr->next)printf("%d ",curr->val);printf("n");}intmain(){intn,m1,m2;scanf("%d %d %d",&n,&m1,&m2);List *s =init(n);List *s1 =init(m1);List *s2 =init(m2);delete(s,s1,s2);traverse(s);return0;}

6 LOCATE 操作

#include<stdio.h>#include<stdlib.h>typedefstructnode{charch;structnode*next,*prev;intfreq;}Node,List;List *init(intn){List *s =(List*)malloc(sizeof(List));Node *head =s;inttmp =1;s->next =s,s->prev =s,s->ch =' ',s->freq =0;while(tmp <=n){charch =getchar();if(ch !=' '&&ch !='\n'){Node *node =(Node*)malloc(sizeof(Node));node->ch =ch,node->freq =0;node->prev =head->prev,node->next =head;head->prev->next =node,head->prev =node;++tmp;}}returns;}voidupdate(List *s,intm){inttmp =1;while(tmp <=m){charch =getchar();if(ch !=' '&&ch !='\n'){for(Node *curr =s->next;curr !=s;curr =curr->next)if(ch ==curr->ch){++curr->freq;break;}++tmp;}}}// 插入排序(稳定)voidsort(List *s){Node *curr =s->next->next;while(curr !=s){Node *tail =curr->prev,*tmp =curr->next;while(tail !=s &&curr->freq >tail->freq)tail =tail->prev;curr->prev->next =curr->next,curr->next->prev =curr->prev;curr->prev =tail,curr->next =tail->next;tail->next->prev =curr,tail->next =curr;curr =tmp;}}voidtraverse(List *s){for(Node *curr =s->next;curr !=s;curr =curr->next)printf("%c ",curr->ch);printf("n");}intmain(){intn,m;scanf("%d %d",&n,&m);List *s =init(n);update(s,m);sort(s);traverse(s);return0;}

第三章 栈与队列

1 表达式括号匹配

// 本题只能使用 fgets, 使用 scanf 和 getchar 均会 WA#include<stdio.h>#include<stdbool.h>charstr[1005]="";charstack[1005]={};inttop =-1;boolisMatched(void){fgets(str,1000,stdin);char*ch =str;while(*ch){switch(*ch){case'(':case'[':case'{':{stack[++top]=*ch;break;}case')':{if(stack[top--]!='(')returnfalse;break;}case']':{if(stack[top--]!='[')returnfalse;break;}case'}':{if(stack[top--]!='{')returnfalse;break;}default:break;}++ch;}if(top ==-1)returntrue;returnfalse;}intmain(){if(isMatched())printf("yes");elseprintf("no");return0;}

2 逆波兰表达式

#include<stdio.h>#include<stdbool.h>#include<string.h>#include<ctype.h>charcalc[1005]="";charoutput[1005]="";charstack[1005]={};inttop =-1;boolisPrior(charcurr,chartopCh){return(((curr =='*')||(curr =='/'))&&((topCh =='+')||(topCh =='-')))||(topCh =='(')||(curr =='(');}voidsuffix(void){char*ch =calc;while(*ch){if(*ch =='\n')break;// 字母跳过if(isalpha(*ch))strncat(output,ch,1);// 入栈: 栈空; 优先级严格大于栈顶; 栈顶为左括号; 左括号elseif(top ==-1||isPrior(*ch,stack[top]))stack[++top]=*ch;// 出栈: 遇到右括号时出栈到左括号elseif(*ch ==')'){while(stack[top]!='('){strncat(output,&stack[top],1);--top;}// 左括号出栈--top;// 出栈: 优先级等于或小于栈顶时, 出栈到严格大于或左括号或栈空}else{while(top !=-1&&!isPrior(*ch,stack[top])){strncat(output,&stack[top],1);--top;}// 入栈stack[++top]=*ch;}++ch;}// 栈中剩余符号全部出栈while(top !=-1){strncat(output,&stack[top],1);--top;}}intmain(){fgets(calc,1000,stdin);suffix();printf("%s",output);return0;}

3 循环队列

#include<stdio.h>intqueue[1005]={};intrear =0,len;intmain(){scanf("%d",&len);while(1){scanf("%d",&queue[rear++]);charch =getchar();if(ch =='n')break;}if(rear >=len){// 队满输出 yesprintf("yesn");rear =len;}elseprintf("no\n");intval,front =0;scanf("%d",&val);while(front <rear &&queue[front]!=val)++front;++front;for(inti =front;i <rear -1;++i){printf("%d ",queue[i]);}// 会判空格与换行符printf("%d\n",queue[rear -1]);printf("%d",queue[front]);return0;}

4 k k k阶斐波那契数列

#include<stdio.h>intbp[1005]={};intmain(){intm,k;scanf("%d %d",&m ,&k);intrear =0,sum =0;bp[k -1]=1;while(1){sum =0;// 循环数组for(inti =0;i <k;++i)sum +=bp[(i +rear)%k];if(bp[rear]<=m &&sum >m)break;bp[rear]=sum;rear =(rear +1)%k;}for(inti =0;i <k;++i)printf("%d ",bp[(rear +i)%k]);printf("\n");return0;}

5 循环右移

#include<stdio.h>intarr[105]={};voidreverse(intleft,intright){while(left <right){inttmp =arr[left];arr[left]=arr[right],arr[right]=tmp;++left,--right;}}intmain(){intn,k;scanf("%d %d",&n,&k);for(inti =0;i <n;++i)scanf("%d",&arr[i]);// 循环移动 = 三次翻转reverse(0,n -1);reverse(0,k -1);reverse(k,n -1);for(inti =0;i <n;++i)printf("%d ",arr[i]);printf("n");return0;}

第五章 数组与广义表

1 以三元组表为存储结构实现矩阵相加

#include<stdio.h>intmain(){intt1,t2;scanf("%d %d",&t1,&t2);intS1[t1][3],S2[t2][3],S[t1 +t2][3];for(inti =0;i <t1;++i)scanf("%d %d %d",&S1[i][0],&S1[i][1],&S1[i][2]);for(inti =0;i <t2;++i)scanf("%d %d %d",&S2[i][0],&S2[i][1],&S2[i][2]);inth1 =0,h2 =0,h =0;while(h1 <t1 &&h2 <t2){if(S1[h1][0]<S2[h2][0]){S[h][0]=S1[h1][0],S[h][1]=S1[h1][1],S[h][2]=S1[h1][2];++h1;}elseif(S1[h1][0]>S2[h2][0]){S[h][0]=S2[h2][0],S[h][1]=S2[h2][1],S[h][2]=S2[h2][2];++h2;}else{if(S1[h1][1]<S2[h2][1]){S[h][0]=S1[h1][0],S[h][1]=S1[h1][1],S[h][2]=S1[h1][2];++h1;}elseif(S1[h1][1]>S2[h2][1]){S[h][0]=S2[h2][0],S[h][1]=S2[h2][1],S[h][2]=S2[h2][2];++h2;}else{S[h][0]=S1[h1][0],S[h][1]=S1[h1][1],S[h][2]=S1[h1][2]+S2[h2][2];++h1,++h2;}}if(S[h][2]!=0)++h;}for(inti =0;i <h &&S[i][0];++i)printf("%d %d %d\n",S[i][0],S[i][1],S[i][2]);return0;}

2 以十字链表为存储结构实现矩阵相加

#include<stdio.h>#include<stdlib.h>typedefstructNode{intraw,col,val;structNode*down,*right;}Node,CList;CList *createCList(intraw,intcol){CList *c =(CList*)malloc(sizeof(CList));c->raw =raw,c->col =col,c->val =-1;c->down =c->right =c;for(inti =raw;i >0;--i){Node *tmp =(Node*)malloc(sizeof(Node));tmp->val =-1,tmp->raw =i,tmp->col =0;tmp->right =tmp,tmp->down =c->down,c->down =tmp;}for(inti =col;i >0;--i){Node *tmp =(Node*)malloc(sizeof(Node));tmp->val =-1,tmp->raw =0,tmp->col =i;tmp->down =tmp,tmp->right =c->right,c->right =tmp;}returnc;}voidinsertOrAdd(CList *head,intraw,intcol,intval){Node *curr =head;for(inti =1;i <=raw;++i)curr =curr->down;while(curr->right->col <col &&curr->right->col !=0)curr =curr->right;// 狠狠地偷懒, 插入同时算加法, 避免额外逻辑if(curr->right->col ==col){curr->right->val +=val;// 单独判断相加后为 0 情况if(curr->right->val ==0){Node *vert =curr->right,*temp =vert;while(vert->down !=temp)vert =vert->down;curr->right =temp->right,vert->down =temp->down;free(temp);}return;}Node *node =(Node*)malloc(sizeof(Node));node->right =curr->right,curr->right =node;curr =head;for(inti =1;i <=col;++i)curr =curr->right;while(curr->down->raw <raw &&curr->down->raw !=0)curr =curr->down;node->down =curr->down,curr->down =node;node->raw =raw,node->col =col,node->val =val;}voidtraverse(CList *S){for(Node *r =S->down;r !=S;r =r->down){for(Node *c =r->right;c !=r;c =c->right){printf("%d %d %dn",c->raw,c->col,c->val);}}}intmain(){intn,m,t1,t2,r,c,v;scanf("%d %d %d %d",&n,&m,&t1,&t2);CList *S1 =createCList(n,m);for(inti =t1;i >0;--i){scanf("%d %d %d",&r,&c,&v);insertOrAdd(S1,r,c,v);}for(inti =t2;i >0;--i){scanf("%d %d %d",&r,&c,&v);insertOrAdd(S1,r,c,v);}traverse(S1);return0;}

3 求广义表深度

#include<stdio.h>// 偷分大法秒了 :)voidfoo(charstr[]){intcnt =0,depth =0;for(char*ch =str;*ch;++ch){if(*ch =='(')++cnt;if(*ch ==')')--cnt;depth =cnt >depth ?cnt :depth;}printf("%d\n",depth);}voidbar(charstr[]){intcnt =0,depth =0;for(char*ch =str;*ch;++ch){if(*ch ==')')++cnt;if(*ch =='(')--cnt;depth =cnt <depth ?cnt :depth;}depth =-depth;printf("%d\n",depth);}intmain(){charstr[1005]="";fgets(str,1000,stdin);foo(str);bar(str);return0;}

第六章 树与二叉树

1 建立二叉树的二叉链表存储结构

#include<stdio.h>#include<stdlib.h>#include<ctype.h>typedefstructnode{structnode*left,*right;charch;}Node,Tree;Node *newNode(charch){Node *node =(Node*)malloc(sizeof(Node));node->ch =ch,node->left =node->right =NULL;returnnode;}// 前序读入Tree *createTree(void){// 边读边插charch =getchar();Node *curr =newNode(ch);ch =getchar();if(ch =='('){curr->left =createTree();curr->right =createTree();}elseif(ch ==','){curr->left =curr->right =NULL;}elseif(ch ==')'){getchar();curr->left =curr->right =NULL;}returncurr;}// 前序遍历voidpreTraverse(Node *curr){if(!curr)return;printf("%c",curr->ch);preTraverse(curr->left);preTraverse(curr->right);}// 偷分大法voidfoo(void){charstr[105]="";scanf("%s",str);for(inti =0;str[i];++i)if(isupper(str[i])||str[i]=='#')putchar(str[i]);}intmain(){Tree *t =createTree();preTraverse(t);//	foo();return0;}

2 计算二叉树叶子节点数目

#include<stdio.h>#include<stdlib.h>typedefstructnode{structnode*left,*right;charch;}Node,Tree;intcnt =0;Node *newNode(charch){Node *node =(Node*)malloc(sizeof(Node));node->ch =ch,node->left =node->right =NULL;returnnode;}Tree *createTree(void){charch =getchar();Node *curr =NULL;if(ch !='#'){curr =newNode(ch);curr->left =createTree();curr->right =createTree();}returncurr;}voidfoo(void){charstr[105]="";scanf("%s",str);for(inti =0;str[i];++i)if(str[i]=='#'&&str[i +1]=='#')++cnt,++i;printf("%dn",cnt);}voidpreTraverse(Node *curr){if(!curr)return;// 遍历并判断if(!curr->left &&!curr->right)++cnt;preTraverse(curr->left);preTraverse(curr->right);}intmain(){Tree *t =createTree();preTraverse(t);printf("%dn",cnt);//	foo();return0;}

3 输出以二叉树表示的算术表达式

#include<stdio.h>#include<stdlib.h>typedefstructnode{structnode*left,*right;charch;}Node,Tree;Node *newNode(charch){Node *node =(Node*)malloc(sizeof(Node));node->ch =ch,node->left =node->right =NULL;returnnode;}Tree *createTree(void){charch =getchar();Node *curr =NULL;if(ch !='#'){curr =newNode(ch);curr->left =createTree();curr->right =createTree();}returncurr;}// 中序输出voidpreTraverse(Node *curr){if(!curr)return;preTraverse(curr->left);printf("%c",curr->ch);preTraverse(curr->right);}intmain(){Tree *t =createTree();preTraverse(t);return0;}

4 建立二叉树的二叉链表

#include<stdio.h>#include<stdlib.h>#include<string.h>typedefstructnode{structnode*left,*right;charch;}Node,Tree;Node *newNode(charch){Node *node =(Node*)malloc(sizeof(Node));node->ch =ch,node->left =node->right =NULL;returnnode;}charpre[105]="";charin[105]="";Tree *createTree(intfl,intfr,intil,intir){if(fl >fr ||il >ir)returnNULL;charrootCh =pre[fl];// 每次前序的头部为根节点 (后序则为尾部)Node *root =newNode(rootCh);intidx =0;for(inti =il;i <=ir;++i)if(in[i]==rootCh){idx =i;break;}intlsSize =idx -il;root->left =createTree(fl +1,fl +lsSize,il,idx -1);root->right =createTree(fl +lsSize +1,fr,idx +1,ir);returnroot;}// 后序遍历voidpostTraverse(Tree *t){if(!t)return;postTraverse(t->left);postTraverse(t->right);printf("%c",t->ch);}intmain(){scanf("%s",pre);scanf("%s",in);intfLen =strlen(pre);intiLen =strlen(in);Tree *t =createTree(0,fLen -1,0,iLen -1);postTraverse(t);return0;}

第七章 图

1 基于图的深度优先搜索策略

#include<stdio.h>#include<stdlib.h>#include<stdbool.h>#defineMAXSIZE1000typedefstructnode{intv;structnode*next;}Node,Graph;// 记录访问情况,避免有环时死循环boolisVisited[MAXSIZE]={};// 外部记录是否能遍历到boolisPath =false;Graph *createGraph(intn,intm){// 指针数组记录邻接表Graph *g =(Graph*)malloc(sizeof(Graph)*(n +1));g[0].v =-1,g[0].next =NULL;for(inti =1;i <=n;++i){scanf("%d",&g[i].v);g[i].next =NULL;}for(inti =1;i <=m;++i){intv1,v2;scanf("%d %d",&v1,&v2);Node*newNode =(Node*)malloc(sizeof(Node));newNode->v =v2,newNode->next =NULL;Node *tail =&g[v1];while(tail->next)tail =tail->next;tail->next =newNode;}returng;}voiddfs(Graph*g,intv1,intv2){Node *curr =&g[v1];while(curr){if(curr->v ==v2)isPath =true;if(!isVisited[curr->v]){isVisited[curr->v]=true;dfs(g,curr->v,v2);}curr =curr->next;}return;}intmain(){intn,m;scanf("%d %d",&n,&m);Graph *g =createGraph(n,m);intv1,v2;scanf("%d %d",&v1,&v2);dfs(g,v1,v2);if(isPath)puts("yes");elseputs("no");return0;}

2 基于图的广度优先搜索策略

#include<stdio.h>#include<stdlib.h>#include<stdbool.h>#defineMAXSIZE100typedefstructnode{intv;structnode*next;}Node,Graph;boolisVisited[MAXSIZE]={};intqueue[MAXSIZE]={};intfront =0,rear =0;Graph *createGraph(intn,intm){Graph *g =(Graph*)malloc(sizeof(Graph)*(n +1));g[0].v =-1,g[0].next =NULL;for(inti =1;i <=n;++i){scanf("%d",&g[i].v);g[i].next =NULL;}for(inti =1;i <=m;++i){intv1,v2;scanf("%d %d",&v1,&v2);Node*newNode =(Node*)malloc(sizeof(Node));newNode->v =v2,newNode->next =NULL;Node *tail =&g[v1];while(tail->next)tail =tail->next;tail->next =newNode;}returng;}boolbfs(Graph *g,intv1,intv2){queue[rear++]=v1;isVisited[v1]=true;while(front !=rear){v1 =queue[front++];// 循环队列front =front ==(MAXSIZE -1)?0:front;Node *curr =&g[v1];while(curr){if(curr->v ==v2)returntrue;if(!isVisited[curr->v]){queue[rear++]=curr->v;// 循环队列rear =rear ==(MAXSIZE -1)?0:rear;isVisited[curr->v]=true;}curr =curr->next;}}returnfalse;}intmain(){intn,m;scanf("%d %d",&n,&m);Graph *g =createGraph(n,m);intv1,v2;scanf("%d %d",&v1,&v2);if(bfs(g,v1,v2))puts("yes");elseputs("no");return0;}

3 逆波兰表达式

#include<stdio.h>#include<stdbool.h>#include<string.h>#include<ctype.h>charcalc[1005]="";charoutput[1005]="";// 栈, 何尝不是一种有向无环图?charstack[1005]={};inttop =-1;boolisPrior(charcurr,chartopCh){return(((curr =='*')||(curr =='/'))&&((topCh =='+')||(topCh =='-')))||(topCh =='(')||(curr =='(');}voidsuffix(void){char*ch =calc;while(*ch){if(*ch =='\n')break;if(isalpha(*ch))strncat(output,ch,1);elseif(top ==-1||isPrior(*ch,stack[top]))stack[++top]=*ch;elseif(*ch ==')'){while(stack[top]!='('){strncat(output,&stack[top],1);--top;}--top;}else{while(top !=-1&&!isPrior(*ch,stack[top])){strncat(output,&stack[top],1);--top;}stack[++top]=*ch;}++ch;}while(top !=-1){strncat(output,&stack[top],1);--top;}}intmain(){fgets(calc,1000,stdin);suffix();printf("%s",output);return0;}

4 Dijkstra 算法

#include<stdio.h>#include<stdbool.h>#defineMAXSIZE100#defineINF0x3f3f3f3fintvn =0,en =0;intdist[MAXSIZE +1][MAXSIZE +1]={};boolisVisited[MAXSIZE +1]={};intlen[MAXSIZE +1]={};voidinit(void){scanf("%d %d",&vn,&en);for(inti =1;i <=vn;++i)for(intj =1;j <=vn;++j)dist[i][j]=INF;for(inti =1;i <=en;++i){intv1,v2,e;scanf("%d %d %d",&v1,&v2,&e);dist[v1][v2]=e;}}voiddijkstra(void){for(inti =1;i <=vn;++i)len[i]=dist[1][i];isVisited[1]=true;for(inti =1;i <=vn -1;++i){intminLen =INF,v =i +1;for(intj =1;j <=vn;++j)if(!isVisited[j]&&len[j]<minLen)minLen =len[j],v =j;isVisited[v]=true;// 输出时将 INF 按照题目要求换为 -1intlenAns =len[v]==INF ?-1:len[v];printf("%d %d %dn",1,v,lenAns);for(intj =1;j <=vn;++j)if(!isVisited[j]&&dist[v][j]!=INF &&len[j]>len[v]+dist[v][j])len[j]=len[v]+dist[v][j];}}intmain(){init();dijkstra();return0;}

第八章 查找

1 构造哈希表

#include<stdio.h>#include<string.h>#include<stdlib.h>inthashFunc(intn){return(3*n)%11;}voidsearch(void){intdata[8]={22,41,53,46,30,13,01,67};inthashVal[11];memset(hashVal,-1,sizeof(hashVal));intsum =0;for(inti =0;i <8;++i){intk =hashFunc(data[i]),n =1;while(hashVal[k]!=-1)k =(k +12)%11,++n;hashVal[k]=data[i];sum +=n;}printf("%d\n",sum /8);}// 这不直接偷分?voidfoobar(void){puts("2");}intmain(){search();//	foobar();return0;}

2 二叉排序树的判别

#include<stdio.h>#include<stdlib.h>#include<stdbool.h>typedefstructnode{intval;structnode*left,*right;}Node,Tree;Node *newNode(intval){Node *node =(Node*)malloc(sizeof(Node));node->val =val,node->left =node->right =NULL;returnnode;}// 记录递归中更新的最小值inttMin =-1;Tree *createTree(void){intn;scanf("%d",&n);Node*curr =NULL;if(n !=-1){curr =newNode(n);curr->left =createTree();curr->right =createTree();}returncurr;}boolisSearchTree(Tree *t){if(!t)returntrue;if(!isSearchTree(t->left))returnfalse;if(t->val <tMin)returnfalse;tMin =t->val;if(!isSearchTree(t->right))returnfalse;returntrue;}intmain(){Tree *t =createTree();if(isSearchTree(t))puts("yes");elseputs("no");return0;}

3 二叉排序树的插入和删除

#include<stdio.h>#include<stdlib.h>#include<limits.h>typedefstructnode{intval;structnode*left,*right;}Node,Tree;Node *newNode(intval){Node *node =(Node*)malloc(sizeof(Node));node->val =val,node->left =node->right =NULL;returnnode;}Tree *createTree(void){intn;scanf("%d",&n);Node*curr =NULL;if(n !=-1){curr =newNode(n);curr->left =createTree();curr->right =createTree();}returncurr;}voidinTraverse(Tree *t,inta,intb){if(!t)return;inTraverse(t->left,a,b);if(a <t->val &&t->val <b)printf("%d ",t->val);inTraverse(t->right,a,b);}// 插入一定发生在叶子节点上Tree *insert(Tree *t,intval){if(!t){t =(Node*)malloc(sizeof(Node));t->val =val,t->left =t->right =NULL;returnt;}if(t->val ==val)returnt;if(t->val >val){t->left =insert(t->left,val);returnt;}t->right =insert(t->right,val);returnt;}Tree *delete(Tree *t,intval){if(!t)returnNULL;if(t->val ==val){Node *l =t->left,*r =t->right;// 分四种情况讨论,应该可以优化,懒得想了if(!l &&!r){free(t);returnNULL;}elseif(!l){free(t);returnr;}elseif(!r){free(t);returnl;}else{if(r->left){while(r->left->left)r =r->left;}elser =t;t->val =r->left->val;free(r->left);r->left =NULL;returnt;}}elseif(t->val >val){t->left =delete(t->left,val);returnt;}else{t->right =delete(t->right,val);returnt;}}intmain(){Tree *t =createTree();inta,b;scanf("%d %d",&a,&b);inTraverse(t,a,b);printf("n");intins;scanf("%d",&ins);t =insert(t,ins);inTraverse(t,INT_MIN,INT_MAX);printf("n");intdel;scanf("%d",&del);t =delete(t,ins);t =delete(t,del);inTraverse(t,INT_MIN,INT_MAX);printf("n");return0;}

4 二叉排序树的合并

#include<stdio.h>#include<stdlib.h>typedefstructnode{intval;structnode*left,*right;}Node,Tree;Node *newNode(intval){Node *node =(Node*)malloc(sizeof(Node));node->val =val,node->left =node->right =NULL;returnnode;}Tree *createTree(void){intn;scanf("%d",&n);Node*curr =NULL;if(n !=-1){curr =newNode(n);curr->left =createTree();curr->right =createTree();}returncurr;}Tree *insert(Tree *t,intval){if(!t){t =(Node*)malloc(sizeof(Node));t->val =val,t->left =t->right =NULL;returnt;}if(t->val ==val)returnt;if(t->val >val){t->left =insert(t->left,val);returnt;}t->right =insert(t->right,val);returnt;}voidmerge(Tree *t1,Tree *t2){if(!t1 ||!t2)return;// 遍历 t2 节点依次插入 t1t1 =insert(t1,t2->val);merge(t1,t2->left);merge(t1,t2->right);}voidinTraverse(Tree *t){if(!t)return;inTraverse(t->left);printf("%d ",t->val);inTraverse(t->right);}intmain(){Tree *t1 =createTree();Tree *t2 =createTree();merge(t1,t2);inTraverse(t1);return0;}

考试题目(回忆版)

  • 顺序表查找(可用二分法)
  • Dijkras 最短路径
  • 四则运算(无括号;中缀变为后缀;后缀直接计算)
  • 拓扑排序(多个选择时最小结点优先)
  • 二叉树前序中序输出后序 / 后序中序输出前序
  • Huffman 编码及解码