文件
我们知道fopen(“文件名和文件储存的类别”,”以什么形态展开”);
比如fopen(“xxx.txt”,”r”);
因为我们知道fopen,如果文件打开成功则返回一个文件的指针,可以用这个指针进行读取数据如果没有打开则返回NULL;
所以用指针来接fopen;
FILE *fp;
打开文件时fscanf(fp,“所在文件的数据格式”,你想将数组存到的地方);
比如
fscanf(fp,"%s %s %s %lf %lf\n",student[i].number,student[i].name,student[i].sex,&student[i].Escore,&student[i].Mscore);
最后关闭文件
fclose(fp);
大体模型是:
*FILE fp;
fp=fopen(“xxx.txt”,”r”);
if(fp)
{
for(int i=0;i<b;i++)//b行
fscanf(fp,”%d %f\n”,&data,&num);
}
else
{
printf(“文件无法打开\n”);
}
图的dfs递归遍历:
#include<stdio.h>
#include<stdlib.h>
const int maxn=20;
int n,color[maxn],tt,f[maxn],g[maxn];
int Map[maxn][maxn];
//这个点已经被访问过了-1;这个点还没有被访问过-2;这个点正在被访问-3;
void initMap(int n)
{
for(int i = 0 ;i < n ; i++)
for(int j = 0 ;j < n ; j++)
{
Map[i][j]=0;
}
}
void dfs_visit(int u)
{
color[u]=3;
f[u]=++tt;
for(int i = 0; i < n; i++)
{
if(Map[u][i] == 0)continue;
else{
if(color[i] == 2)dfs_visit(i);
}
}
color[u]=1;
g[u]=++tt;
}
void dfs()
{
int u;
for(u = 0; u < n; u++)
{
color[u]=2;
}
tt=0;
for(u = 0; u < n; u++)
{
if(color[u]==2)dfs_visit(u);
}
for(u = 0; u < n; u++)
{
printf("%d : 最开始被访问的时候: %d 结束访问的时候: %d\n",u+1,f[u],g[u]);
}
}
int main ()
{
int p,t,q;
printf("亲~输入图的顶点个数:\n");
scanf("%d", &n);
initMap(n);
printf("这个顶点是谁?它的小伙伴有几个鸭~\n");
for(int i = 0 ; i < n ; i++)
{
scanf("%d %d",&q,&t);
q--;
for(int j = 0 ; j < t ; j++)
{
scanf("%d", &p);
p--;
Map[q][p]=1;
}
}
dfs();
}
非递归遍历(利用栈~)
图的非递归遍历和递归遍历的步骤差不多 main函数和dfs函数都可以不变
。
因为main函数进行的是邻接表变成邻接矩阵,dfs进行的是初始化标记数组color[maxn]和对n个顶点的逐个dfs。
但dfs_visit函数不递归,即栈:
首先将第一个点进入栈中并将它标记为正在使用。然后用while(!(s.empty()))进行操作:首先看栈顶元素的所连元素是否存在,所以需要一个next(i)函数查看并返回,先不管它。
1.如果next返回的有值则那个值入栈,初始数组和标记color数组改变。
2.如果next返回无值则s.pop(),栈顶元素出栈,结束数组和标记color数组改变。
即让第一个点的所有邻接点入栈。为什么呐~
因为虽然我们从纸上看算法是如图二叉树先序遍历一个一个来的,但是在计算机语言里却需要把第一个的邻接点全部入栈在进行,否则的话无法将一个个遍历连接起来。这个我们画一个邻接矩阵会好理解点:
下面是非递归栈的代码
int next(int q)
{
for(int i=0;i<n;i++)
{
if(Map[q][i]==1&&color[i]==2)
{
return i;
}
}
return 31;
}
void dfs_visit(int u)
{
stack<int>s;
int p,q;
s.push(u);
color[u]== 3;
f[u]=++tt;
while( !(s.empty()) )
{
q = s.top();
p = next(q);
if(p!=31)
{
if(color[p]==2)
{
color[p] = 3;
f[p]=++tt;
s.push(p);
}
}
else{
s.pop();
color[q]=1;
g[q]=++tt;
}
}
}
BFS
利用队列,队列的特点是:后进先出,所以先一个元素进队立刻出队,然后找这个元素的所有邻接点并依次入队,然后前面的front指针所指出队,其邻接点依次在之后入队,然后重复;
#include<iostream>
#include<algorithm>
using namespace std;
#include<queue>
const int maxn=50;
const int mini=99;
int Map[maxn][maxn],d[maxn];
int n;
void initmap(int n)
{
for(int i=0;i<n;i++)
for(int j=0; j<n ;j++)
Map[i][j]=0;
}
void bfs(int u)
{
queue<int >s;
for(int i=0;i<n;i++)
d[i]= mini;
int p,q;
d[u]=0;
s.push(u);
while(!(s.empty()))
{
p=s.front();
s.pop();
for(int z=0;z<n;z++)
{
if(Map[p][z]==0)continue;
if(d[z]!=mini)continue;
d[z]=d[p]+1;
s.push(z);
// printf("liliilili\n");
}
//printf("wawawawawa\n");
}
for(int j=0;j<n;j++)
{
printf("%d %d \n",j+1,d[j]);
}
}
int main()
{
int q,p,k;
scanf("%d",&n);
initmap(n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&q,&k);
q--;
for(int j =0 ;j < k; j++)
{
scanf("%d",&p);
p--;
Map[q][p]=1;
}
}
bfs(0);
}