关于文件的输入输出,只要在主函数中添加:
freopen("E:\read9.txt","r",stdin);
freopen("E:\write9.txt","w",stdout);
即可。
其余地方的输入输出不变,但是必须用scanf和printf进行输入输出。
实验一 迷宫问题(bfs)
#include"iostream" #include"stdio.h" #include"algorithm" #include"queue" #include"string.h" #include"cmath" #include"stack" #include"fstream" #define mx 105 #define inf 1000 using namespace std; int n,m; int sx,sy,ex,ey; int maze[mx][mx],vis[mx][mx]; int dir[8][2]= {{0,1},{0,-1},{1,0},{-1,0},{-1,-1},{-1,1},{1,-1},{1,1}}; bool judge(int x,int y) { if(maze[x][y]==0&&x>=0&&x<n&&y>=0&&y<m) { return true; } return false; } void output(int step) { int i; stack<int>path; path.push(ex*m+ey); printf("%s%d ","最少步骤是:",step); int x=ex,y=ey,dx,dy; while(vis[x][y]!=0) { for(i=0;i<8;i++) { dx=x+dir[i][0]; dy=y+dir[i][1]; if(dx>=0&&dx<n&&dy>=0&&dy<m) if(vis[dx][dy]==vis[x][y]-1) { path.push(dx*m+dy); break; } } x=dx;y=dy; } printf("%s","最短路径为:"); while(!path.empty()) { int u=path.top(); path.pop(); x=u/m;y=u%m; if(x!=ex||y!=ey) printf("%s%d%s%d%s%s","(",x,",",y,")","->"); else printf("%s%d%s%d%s ","(",x,",",y,")"); } } void bfs(int step) { queue<int>q; int i,x,y,dx,dy,u; x=sx;y=sy; u=x*m+y; q.push(u); while(!q.empty()) { u=q.front(); q.pop(); x=u/m;y=u%m; if(x==ex&&y==ey) { output(step); return; } int flag=1; step=vis[x][y]; for(i=0;i<8;i++) { dx=x+dir[i][0]; dy=y+dir[i][1]; if(judge(dx,dy)) { if(flag){step++;flag=0;} maze[dx][dy]=1; if(step<vis[dx][dy]) vis[dx][dy]=step; u=dx*m+dy; q.push(u); } } } printf("%s","没有满足条件的通路! "); } int main() { int i,j; freopen("C://read.txt","r",stdin); freopen("C://write.txt","w",stdout); while(scanf("%d%d",&n,&m),n||m) { for(i=0;i<n;i++) { for(j=0;j<m;j++) {scanf("%d",&maze[i][j]);vis[i][j]=inf;} } scanf("%d%d%d%d",&sx,&sy,&ex,&ey); maze[sx][sy]=1; vis[sx][sy]=0; bfs(0); } return 0; }
实验二 锦标赛问题(简单的分治思想)
#include"iostream" #include"stdio.h" #include"cmath" #include"string.h" #include"algorithm" #include"queue" using namespace std; const int mx=1005; int calendar[mx][mx];//日程表 FILE* rfile=fopen("E:\read2.txt","r"); FILE* wfile=fopen("E:\write2.txt","w");//文件读写 void championship(int k) { int i,j,t; calendar[1][1]=1;//只有两个人比赛的情况 calendar[1][2]=2; calendar[2][1]=2; calendar[2][2]=1; int temp=1; for(t=1;t<k;t++) { temp*=2; for(i=1;i<=temp;i++) { for(j=1;j<=temp;j++) { calendar[i+temp][j+temp]=calendar[i][j]; } } for(i=1;i<=temp;i++)//用分治的方式打表 { for(j=1;j<=temp;j++) { calendar[i+temp][j]=calendar[i][j]+temp; } } for(i=temp+1;i<=temp*2;i++) { for(j=1;j<=temp;j++) { calendar[i-temp][j+temp]=calendar[i][j]; } } } int n=pow(2,k); for(i=1;i<=n;i++)//日程表的输出 { for(j=1;j<=n;j++) fprintf(wfile,"%d ",calendar[i][j]); fprintf(wfile,"%s ",""); } fprintf(wfile,"%s ","");//文件输出 } int main() { int k,icase=0; while((fscanf(rfile,"%d",&k),k!=-1)) { fprintf(wfile,"%s%d%s ","Case ",++icase," :"); fprintf(wfile,"%s%d ","input k :",k); championship(k); } fclose(wfile); fclose(rfile); return 0; }
实验三 kruskal算法(最小生成树)
#include"iostream" #include"stdio.h" #include"algorithm" #include"cmath" #include"string.h" #include"string" using namespace std; const int mx=105; const int inf=32767; FILE* rfile=fopen("E:\read3.txt","r"); FILE* wfile=fopen("E:\write3.txt","w");//文件读写 struct Edge//记录边的两个端点和权值 { int u; int v; int w; }; struct Mgraph { int edges[mx][mx];//存储边 int n;//顶点数 }; struct UFStree//并查集的数据结构 { int data;//节点对应的编号 int parent;//节点对应双亲下标 int rank;//节点对应秩 }; bool cmp(const Edge a,const Edge b) { return a.w<b.w; } void Make_set(UFStree t[],int n)//初始化 { for(int i=0;i<n;i++) { t[i].rank=0; t[i].parent=i; } } int Find_set(UFStree t[],int x)//查找集合的代表元素 { while(x!=t[x].parent) x=t[x].parent; return x; } void Union(UFStree t[],int x,int y)//将两个集合并为一个 { x=Find_set(t,x); y=Find_set(t,y); if(t[x].rank>t[y].rank)//将秩小的作为秩大的子集 t[y].parent=x; else { t[x].parent=y; if(t[x].rank==t[y].rank) t[y].rank++; } } void Kruskal(Mgraph g)//求最小生成树的算法 { int i,j,k,u1,v1,sn1,sn2; UFStree t[mx]; Edge E[mx]; k=1; //E数组的下标从1开始 for(i=0;i<g.n;i++) //由g产生的边集E for(j=0;j<g.n;j++) { if(g.edges[i][j]!=0&&g.edges[i][j]!=inf)//取出图的邻接矩阵中所有的边 { E[k].u=i;E[k].v=j;E[k++].w=g.edges[i][j]; } } sort(E,E+k,cmp);//按边的权值从小到大排序 Make_set(t,g.n); k=1;//k表示当前构造生成树的第几条边,初值为1 j=1;//E中边的下标,初值为1 while(k<g.n) { u1=E[j].u; v1=E[j].v; sn1=Find_set(t,u1); sn2=Find_set(t,v1); if(sn1!=sn2)//两定顶点属于不同的集合,该边是最小生成树的一条边 { fprintf(wfile,"%s%d%s%d%s%d ","(",u1,",",v1,"):",E[j].w); k++;//生成边数增1 Union(t,u1,v1);//将 u1和v1两个顶点合并 } j++; } } int main() { Mgraph g; int i,j,n; fprintf(wfile,"%s ","输入顶点数为0时结束!"); while(fscanf(rfile,"%d",&n),n) { fprintf(wfile,"%s%d ","输入图的顶点数目:",n); g.n=n; fprintf(wfile,"%s ","输入每个顶点与n个顶点边的权值:"); for(i=0;i<n;i++) { for(j=0;j<n;j++) {fscanf(rfile,"%d",&g.edges[i][j]);//取地址符很关键 fprintf(wfile,"%d ",g.edges[i][j]); } fprintf(wfile,"%s ",""); } fprintf(wfile,"%s ","输出构成最小生成树的边和顶点集:"); Kruskal(g); fprintf(wfile,"%s ",""); } fclose(wfile);//关闭文件 fclose(rfile); return 0; }
实验四 哈夫曼编码
#include"iostream" #include"stdio.h" #include"algorithm" #include"string" #include"string.h" #include"cmath" #include"fstream" using namespace std; const int mx=105; const int inf=32767;//表示无穷 FILE* rfile=fopen("E:\read4.txt","r"); FILE* wfile=fopen("E:\write4.txt","w"); struct htnode { char data;//节点值 double weight;//权重 int parent;//双亲节点 int lchild;//左孩子节点 int rchild;//右孩子节点 }; struct hcode { char cd[mx];//存放当前结点的哈夫曼码 int start;//cd[start]~cd[n]存放哈夫曼码 }; void CreatHuffman(htnode ht[],int n) { int i,j,k,lnode,rnode; double min1,min2; for(i=0;i<2*n-1;i++)//所有节点的相关域置初值-1 { ht[i].parent=ht[i].lchild=ht[i].rchild=-1; } for(i=n;i<2*n-1;i++)//构造哈弗曼树 { min1=min2=inf; lnode=rnode=-1;//lnode和rnode为最小权重的两个结点位置 for(k=0;k<=i-1;k++)//在ht[]中找权值最小的两个结点 { if(ht[k].parent==-1)//只在尚未构造二叉树的结点中查找 { if(ht[k].weight<min1) { min2=min1;rnode=lnode; min1=ht[k].weight;lnode=k; } else if(ht[k].weight<min2) { min2=ht[k].weight;rnode=k; } } } ht[i].weight=ht[lnode].weight+ht[rnode].weight; ht[i].lchild=lnode;ht[i].rchild=rnode;//ht[i]作为双亲结点 ht[lnode].parent=i;ht[rnode].parent=i; } } void CreatHuffmanCode(htnode ht[],hcode hcd[],int n) { int i,f,c; hcode hc; for(i=0;i<n;i++)//根据哈夫曼树求哈夫曼编码 { hc.start=n;c=i; f=ht[i].parent; while(f!=-1) { if(ht[f].lchild==c) hc.cd[hc.start--]='0'; else hc.cd[hc.start--]='1'; c=f;f=ht[f].parent; } hc.start++;hcd[i]=hc; } } void display(htnode ht[],hcode hcd[],int n) { for(int i=0;i<n;i++) { fprintf(wfile,"%c%s",ht[i].data,": "); for(int j=hcd[i].start;j<=n;j++) fprintf(wfile,"%c",hcd[i].cd[j]); fprintf(wfile,"%s ",""); } fprintf(wfile,"%s ",""); } int main() { htnode ht[mx]; hcode hcd[mx]; char enter;//用于清除换行 int n,i,j; while(fscanf(rfile,"%d",&n),n) { for(i=0;i<n;i++) { fscanf(rfile,"%c%c%lf",&enter,&ht[i].data,&ht[i].weight); } CreatHuffman(ht,n); CreatHuffmanCode(ht,hcd,n); display(ht,hcd,n); } fclose(wfile); fclose(rfile); return 0; }
实验五 树和二叉树
任务(1)和(2):
#include"iostream" #include"stdio.h" #include"algorithm" #include"string" #include"string.h" #include"Stack" #include"queue" #include"vector" //顺序表ADT的定义 //datatype的定义 #ifndef datatype #define datatype NODE #define _ERROR NULL #endif FILE* rfile=fopen("E:\read5.txt","r"); FILE* wfile=fopen("E:\write5.txt","w"); //树结点的定义 struct Tnode{ struct Tnode * lchild; struct Tnode * rchild; char* data;//data用于保存节点信息,类型为字符串 }; typedef struct Tnode * Bitree; typedef struct Tnode * NODE; struct Table{ //为了定义栈 datatype* Table_head; int Length; int Max_Length; }; typedef struct Table* mystable; //栈ADT的定义 typedef struct Table* mystack; //为顺序表分配空间,将所有数据初始化为init mystable Assign(const int maxlen,datatype init) { mystable temp; if((temp=(mystable)malloc(sizeof(struct Table)))!=NULL){//分配空间成功 temp->Max_Length = maxlen; temp->Length=0; if((temp->Table_head=(datatype *)malloc(sizeof(datatype)*maxlen))!=NULL) for(int i=0;i<maxlen;i++) *(temp->Table_head+i)=init; else return NULL; return temp; } return NULL; } //判断表是否为空 int isEmpty(const mystable table) { if (table==NULL) return -1; if(table->Length == 0) return 1; return 0; } //判断表是否为满 int isFull(const mystable table) { if (table==NULL) return -1; if(table->Length == table->Max_Length) return 1; return 0; } //获取position位置的数据 datatype get(const mystable table,int position) { if (position>table->Length-1 || position<0) return _ERROR; return *(table->Table_head + position); } //获取表长 int getLength(const mystable table) { if (table==NULL) return -1; return table->Length; } //从表中删除一个数据 int Remove(const mystable table,int position) { int i=0; if(table==NULL) return -1; if(position>table->Length-1 || position<0) return 0; for(i=position;i<table->Length-1;i++) *(table->Table_head+i)=*(table->Table_head+(i+1)); table->Length--; return 1; } //插入一个数据到position位置 int Insert(mystable table,int position,datatype data) { int i=0; if(table==NULL) return -1; if(position>table->Length || position<0) return 0; if(isFull(table)==0){ for(i=table->Length;i>position;i--) *(table->Table_head+i)=*(table->Table_head+(i-1)); *(table->Table_head+i)=data; table->Length++; }else{ mystable temp; if((temp=(mystable)malloc(sizeof(struct Table)))==NULL) return -1; if((temp->Table_head=(datatype*) malloc(sizeof(datatype)*(table->Max_Length+1)))==NULL) return -1; temp->Length=table->Max_Length+1; temp->Max_Length=table->Max_Length+1; for(i=0;i<position;i++) *(temp->Table_head+i)=*(table->Table_head+i); *(temp->Table_head+i)=data; for(i++;i<temp->Length;i++) *(temp->Table_head+i)=*(table->Table_head+(i-1)); free(table->Table_head); free(table); table=temp; } return 1; } //释放表占用的空间 int del(const mystable table) { free(table->Table_head); free(table); return 1; } //在表的最后插入一个数据 int add(const mystable table,datatype x) { return Insert(table,table->Length,x); } //初始化栈,分配空间 mystack initial() { return Assign(100,0); } //从栈中弹出一个数据 datatype pop(mystack Stack) { if(Stack==NULL) return _ERROR; if(isEmpty(Stack)) return _ERROR; datatype data; data=get(Stack,Stack->Length-1); Remove(Stack,Stack->Length-1); return data; } //返回栈顶的数据但不弹出 datatype peek(mystack Stack) { if(Stack==NULL) return _ERROR; if(isEmpty(Stack)) return _ERROR; datatype data; data=get(Stack,Stack->Length-1); return data; } //向栈中压入数据 int push(mystack Stack,datatype x) { return Insert(Stack,Stack->Length,x); } //分配一个新的树节点 NODE newNode(char* data) { NODE temp=(NODE)malloc(sizeof(struct Tnode)); if(temp==NULL) return NULL; temp->lchild=NULL; temp->rchild=NULL; temp->data=data; return temp; } //字符串转化为中缀顺序表,这是本实验的核心代码 mystable char_to_infix(char ex[]) { int length=strlen(ex); mystable infix=Assign(length,NULL); char* temp; for (int i = 0; i < length; i++) { if ((ex[i] >= '0' && ex[i] <= '9') || ex[i] == '.' ) { //若是数字字符则查询直到遇到一个不是数字的字符 int Count=0; for(int j=i;(ex[j] >= '0' && ex[j] <= '9') || ex[j] == '.';j++,Count++); temp=(char *)malloc(sizeof(char)*(Count+1)); for(int j=0;j<Count;j++) temp[j]=ex[i+j]; temp[Count]='