第1关:迷宫问题
int DFS(int k,int (*a)[3])
{//深度搜索第k层,k:当前路口
/**************begin************/
if(k==m) { //到达出口
tag=1;
return 0;
}
for(int i=0;i<3;i++) {//遍历向左路口、向前路口、向右路口
if(0!=a[k][i]&&tag!=1) {//如果当前路口有通路,并且没有走过
DFS(a[k][i],a);//进入下一个路口 ,递归
}
}
return 0;
/**************end************/
}
第2关:基于Dijsktra算法的最短路径求解
void ShortestPath_DIJ(AMGraph G, char V)
{//用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径
/**************begin************/
int i,n,v,Min,w;
int S[MVNum]; //S[i]记录从源链0到终点
n=G.vexnum; //N列表中的项目数
int v0=LocateVex(G,V);
for(v=0;v<n;++v)
{
S[v]=false; //首为空
D[v]=G.arcs[v0][v]; //分为不同终端的短期数据库的初始初始化更改为右上角的值
if(D[v]<MaxInt)
Path[v]=v0; //V0之间进行选择,并将v的第一个要求设置为V0
else
Path[v]=-1; //如果v0和v0之间没有差异,则v0的第一个要求设置为1
}//for
S[v0]=true; //将0添加到S
D[v0]=0;
for(i=1;i<n;++i)
{
Min=MaxInt;
for(w=0;w<n;++w)
if(!S[w]&&D[w]<Min)
{
v=w;
Min=D[w];
}
S[v]=true; //添加S
for(w=0;w<n;++w)
if(!S[w]&&(D[v]+G.arcs[v][w]<D[w]))
{
D[w]=D[v]+G.arcs[v][w]; //更新D[w]
Path[w]=v; //先前更改w的要求是v
}//if
}//for
/**************end************/
}
第3关:六度空间理论
float SixDegree_DIJ(int G[][MAXSIZE], int n, int start)
{//通过这个“新的开始”,我们可以计算法律系统中六个空时间点的数量,而开始是交换机指定时间点的第一级
/**************begin************/
bool S[MAXSIZE]; //S[]是按以下顺序开始的最短时间
int D[MAXSIZE]; //D[]是以下序列到达起点的最短时间
for (int i=0;i<n;i++) {
S[i]=false;
D[i]=INFINITE;
}
S[start]=true; //将起点添加到S
D[start]=0;
for (int i=0;i<n;i++) {
if (G[start][i]!=0)
D[i]=G[start][i];
}
//初始区域完成或完成后,在相同的环境中启动事件,然后要求系统启动到一定的最小时间长度,然后将其添加到S板
for (int i=0;i<n-1;i++) {
int v=FindMinPath(S, D, n);
if (v==-1) break;
S[v]=true;
for (int w=0;w<n;w++) {
if (!S[w]&&D[w]>D[v]+G[v][w]) {
D[w]=D[v]+G[v][w]; //更新D[w]
}
}
}
//已请求点开始图[]中剩余短周期的数量,剩余短周期数量现在比其他两个短周期数量少,可以作为相关短周期的百分比列
float count=1;
for (int i=0;i<n;i++) {
if (D[i]<=6)
count++;
}
return count/n;
/**************end************/
}
第4关:基于邻接表的新顶点的增加
int InsertVex(ALGragh &G)
{//在以邻接表形式存储的无向图G上插入顶点v
/**************begin************/
if((G.vexnum+1)>MVNum) return ERROR; //判断插入操作是否合法
G.vexnum++; //增加图G的顶点数量
cin>>G.vertices[G.vexnum-1].data; //存入新结点对应的链表的头结点数据域
G.vertices[G.vexnum-1].firstarc=NULL; //指针域赋值为NULL
return OK;
/**************end************/
}
第5关:基于邻接矩阵的新顶点的增加
int InsertVex(AMGragh &G)
{//在以邻接矩阵形式存储的无向图G上插入顶点
/**************begin************/
if((G.vexnum+1)>MVNum) return ERROR; //判断插入操作
G.vexnum++; //增加图G的顶点数量
cin>>G.vexs[G.vexnum]; //将新顶点存入表
for(int k=0;k<G.vexnum;k++) //邻接矩阵相应位置的元素置为0
G.arcs[G.vexnum][k]=G.arcs[k][G.vexnum]=0;
return OK;
/**************end************/
}
第6关:基于邻接表的顶点的删除
int DeleteVex(ALGragh &G)
{//删除G中顶点f及其相关的弧
/**************begin************/
int i,f; //f代表删除的顶点编号
cin>>f;
DeleteAdjList(G.vertices[f-1]); //删除指定顶点链表上的边结点
for(i=f;i<G.vexnum;i++) //把f的顶点信息删除,后面顶点向前移动
{
G.vertices[i-1]=G.vertices[i];
}
G.vexnum--; //顶点数减1
for(i=0;i<G.vexnum;i++) //遍历图G,删除顶点f相关的边
{
VNode p=G.vertices[i]; //p用于指向当前结点的前驱
VNode q=G.vertices[i]; //q用于指向当前结点
if(p.firstarc->data==f) //如果当前结点的第一条边关联的结点为f,则直接删除该边
{
ArcNode *t=G.vertices[i].firstarc;
G.vertices[i].firstarc=t->nextarc;
delete t;
G.arcnum--;
continue;
}
q.firstarc=q.firstarc->nextarc; //继续比较后面的边结点
while(q.firstarc)
{
if(q.firstarc->data==f) //存在与f相关的边,则删除该边
{
p.firstarc->nextarc=q.firstarc->nextarc;
delete q.firstarc;
G.arcnum--;
break;
}
p.firstarc=q.firstarc; //没找到与f关联的边,指针后移
q.firstarc=q.firstarc->nextarc;
}
}
return OK;
/**************end************/
}
第7关:基于邻接表的新边的增加
int InsertArc(ALGragh &G)
{//在以邻接表形式存储的无向图G上插入边
/**************begin************/
int h,k;
cin>>h>>k; //输入一条边的两个顶点h和k
ArcNode* p1=new ArcNode; //生成边结点*p1
p1->adjvex=h-1; //邻接点序号为h-1,即顶点在G.vertices中的序号
p1->data=k;
p1->nextarc=G.vertices[h-1].firstarc; //将新结点*p1插入顶点的边表头部
G.vertices[h-1].firstarc=p1;
ArcNode* p2=new ArcNode; //生成边结点*p2
p2->adjvex=k-1; //邻接点序号为k-1,即顶点在G.vertices中的序号
p2->data=h;
p2->nextarc=G.vertices[k-1].firstarc; //将新结点*p2插入顶点的边表头部
G.vertices[k-1].firstarc=p2;
return OK;
/**************end************/
}
第8关:基于邻接矩阵的新边的增加
int InsertArc(AMGragh &G)
{//在以邻接矩阵形式存储的无向图G上插入边
/**************begin************/
int f,g;
cin>>f>>g;
G.arcs[f-1][g-1]=G.arcs[g-1][f-1]=1; //在邻接矩阵上增加对应的边
G.arcnum++;
return OK;
/**************end************/
}
第9关:基于邻接表的边的删除
int DeleteArc(ALGragh &G)
{//在以邻接表形式存储的无向图G上删除边
/**************begin************/
int f,g;
cin>>f>>g; //f和g代表删除的边所依附的两个顶点
ArcNode *q,*p;
p=G.vertices[f-1].firstarc; //指针p初始化指向顶点vf-1的边表头部
q=p; //q用于指向*p的前驱结点
while(p->data!=g) //遍历链表寻找顶点g
{
q=p;
p=p->nextarc;
}
if(q==p) //如果与顶点vf-1相连的第一个边表就是待删除顶点
{
G.vertices[f-1].firstarc=p->nextarc;
delete p;
G.arcnum--; //边的数目减1
}
else
{
q->nextarc=p->nextarc;
delete p;
G.arcnum--;
}
p=G.vertices[g-1].firstarc; //指针p初始化指向顶点vg-1的边表头部
q=p; //q用于指向*p的前驱结点
while(p->data!=f) //遍历链表寻找顶点f
{
q=p;
p=p->nextarc;
}
if(q==p) //如果与顶点vg-1相连的第一个边表就是待删除边
{
G.vertices[g-1].firstarc=p->nextarc;
delete p;
G.arcnum--; //边的数目减1
}
else
{
q->nextarc=p->nextarc;
delete p;
G.arcnum--;
}
return OK;
/**************end************/
}
第10关:基于邻接矩阵的边的删除
int DeleteArc(AMGragh &G)
{//在以邻接矩阵形式存储的无向图G上删除边
/**************begin************/
int f,g; //f和g代表删除的边所依附的两个顶点
cin>>f>>g;
G.arcs[f-1][g-1]=G.arcs[g-1][f-1]=0; //在邻接矩阵上删除边
G.arcnum--; //边数减1
return OK;
/**************end************/
}
第11关:基于邻接表的深度优先遍历
void DFS(ALGraph G,int v,SqStack S)
{
/**************begin************/
InitStack(S); //构造一个空栈实现非递归过程
Push(S,v); //顶点v进栈
int cnt=0,k;
ArcNode *p;
while(!StackEmpty(S))
{
Pop(S,k); //栈顶元素k出栈
if(!visited[k])
{
cnt++;
if(cnt<G.vexnum) //访问第k个顶点
cout<<k<<" ";
else
cout<<k<<endl;
visited[k]=true;
}
p=G.vertices[k].firstarc; //p指向k的边链表的第一个边结点
while(p!=NULL) //边结点非空
{
if(!visited[p->data]) //如果p->data未被访问,p->data进栈
Push(S,p->data);
p=p->nextarc; //p指向下一个边结点
}
}//while
/**************end************/
}
第12关:最长的最短路径的求解
void ShortPathMAX(AMGraph G,int v0)
{//用Dijkstra算法求解
/**************begin************/
bool* S=new bool[G.vexnum+1]; //顶点集S,初始值为false
int* Path=new int[G.vexnum+1];
int* D=new int[G.vexnum+1]; //保存v0到其他所有顶点的最短路径
int i,j,Min,Min_j,k,Max,Max_j;
for(i=1;i<=G.vexnum;i++) { //初始化
S[i]=false;
D[i]=G.arcs[v0][i]; //将v0到各个终点的最短路径长度初始化为弧上的权值
if(D[i]==MaxInt)
Path[i]=ERROR; //如果v0和v之间无弧,则将v的前驱置为ERROR
else
Path[i]=v0; //如果v0和v之间有弧,则将v的前驱置为v0
}
S[v0]=true; //将v0加入S
D[v0]=0;
//主循环,每次求得v0到某个顶点v的最短路径,将v加到S集
for(i=1;i<=G.vexnum;i++) { //依次进行计算其余顶点
Min=MaxInt;
for(j=1;j<=G.vexnum;j++) {
if(!S[j]&&D[j]<Min) { //选择一条当前的最短路径,终点为Min_j
Min_j=j;
Min=D[j];
}
}
S[Min_j]=true; //将Min_j加入S
for(k=1;k<=G.vexnum;k++) { //更新从v0出发到集合V-S上所有顶点的最短路径长度
if(!S[k]&&(D[Min_j]+G.arcs[Min_j][k]<D[k])) {
D[k]=D[Min_j]+G.arcs[Min_j][k]; //更新D[k]
Path[k]=Min_j; //更新k的前驱为Min_j
}
}
//设距离顶点v0的最短路径长度最大的一个顶点为Max_j
Max=0;
for(i=1;i<=G.vexnum;i++) {
if(Max<D[i]) {
Max=D[i];
Max_j=i;
}//if
}//for
cout<<Max_j<<endl; //最短路径最长的顶点编号
cout<<Max<<endl; //两点的最短距离
}//for
/**************end************/
}
第13关:基于深度优先搜索的两顶点路径存在与否的判断
int PathDFS(ALGragh G,int i,int j)
{
/**************begin************/
if(i==j) return OK; //递归结束的条件,首尾相遇,存在路径
else
{
visited[i]=true; //顶点i访问标志为true
ArcNode *p;
for(p=G.vertices[i].firstarc;p;p=p->nextarc,level--)
{
level++; //递归层加1
int k=p->adjvex;
if(!visited[k]&&PathDFS(G,k,j))
return OK; //i下游的顶点到j有路径
}
}
if(level==1) return ERROR; //i到j没有路径
return ERROR;
/**************end************/
}
第14关:基于邻接表的长度为k的简单路径的求解
int CreateUDG(ALGragh &G,int vexnum,int arcnum,char ch[])
{//采用邻接表表示法,创建无向图G
/**************begin************/
G.vexnum=vexnum; //输入总顶点数
G.arcnum=arcnum; //输入总边数
if(G.vexnum>MVNum) return ERROR; //超出最大顶点数则结束函数
for(int i=0;i<G.vexnum;i++) { //构造表头结点表
G.vertices[i].data=ch[i]; //输入顶点值
G.vertices[i].firstarc=NULL; //初始化表头结点的指针域为NULL
}
for(int j=0;j<G.arcnum;j++) { //遍历图中所有边
char h,p;
cin>>h>>p;
ArcNode* p1=new ArcNode; //创建一个新的ArcNode对象p1,表示从顶点h到顶点p的边
int pos2=Locate(ch,p); //在ch数组中找到顶点p的位置pos2
p1->adjvex=pos2;
p1->data=p;
int pos1=Locate(ch,h); //在ch数组中找到顶点h的位置pos1
p1->nextarc=G.vertices[pos1].firstarc; //将p1插入到顶点h的边链表的头部
G.vertices[pos1].firstarc=p1; //更新顶点h的第一条边为p1
ArcNode* p2=new ArcNode; //表示从顶点p到顶点h的边
p2->adjvex=pos1;
p2->data=h;
p2->nextarc=G.vertices[pos2].firstarc; //将p2插入到顶点p的边链表的头部
G.vertices[pos2].firstarc=p2; //更新顶点p的第一条边为p2
}
return OK;
/**************end************/
}
第15关:基于邻接矩阵的顶点的删除
int DeleteVex(AMGragh &G)
{
/**************begin************/
int i,j,f; //f代表要删除的顶点编号
cin>>f;
for(i=f-1;i<G.vexnum-1;i++) { //从目标顶点所在行开始,用下一行的边的权值逐行覆盖上一行边的权值
for(j=0;j<G.vexnum;j++) {
G.arcs[i][j]=G.arcs[i+1][j];
}
}
G.vexnum--; //图的顶点数减1
for(i=0;i<G.vexnum;i++){ //从目标顶点所在列开始,用后一列的边的权值逐列覆盖前一列边的权值
for(j=f-1;j<G.vexnum;j++){
G.arcs[i][j]=G.arcs[i][j+1];
}
}
for(i=f;i<=G.vexnum;i++) //更新顶点表
G.vexs[i]=G.vexs[i+1];
return OK;
/**************end************/
}