头歌实践教学平台——数据结构

目录

一、迷宫问题

任务描述

编程要求

输入

输出

测试说明

二、基于Dijsktra算法的最短路径求解

三、六度空间理论

四、基于邻接表的新顶点的增加

五、基于邻接矩阵的新顶点的增加


一、迷宫问题

任务描述

密密被困在一个迷宫里,迷宫有n个路口,编号为1-n。密密现在站在第一个路口,出口编号为m。先给出每个路口通向何处,问密密能否逃出迷宫。

编程要求

输入

多组数据,每组数据n+2行。第一行为一个正整数n代表路口的个数,之后n行,这n行中的第i行为第i个路口的向左路口、向前路口、向右路口。最后一行为一个正整数m代表迷宫的终点。当n=0时输入结束。

输出

每组数据输出一行,若密密能走出迷宫,输出“YES”,否则输出“NO”。

测试说明

平台会对你编写的代码进行测试:

测试输入:

6

0 2 0

3 5 6

0 0 4

0 0 0

0 0 0

7 0 0

7

3

2 0 0

0 0 0

0 0 0

3

0

预期输出:

YES

NO

#include <iostream>
using namespace std;
int m,n;//m:出口编号  n:入口
int tag;//输出标记
int DFS(int k,int (*a)[3])
{//深度搜索第k层,k:当前路口
/**************begin************/
	int i,j;
	if(k==m)//到达出口
	{
		tag=1;
		return 0;
	}
	for(i=0;i<3;i++)//遍历三个路口
	{
		if(0!=a[k][i]&&tag!=1)//如果当前路口有通路,并且没有走过
		{
			DFS(a[k][i],a);//进入下一个路口 ,递归
		}
	}
	return 0;
    /**************end************/
}
int main()
{
	while(cin>>n)
	{
	if(n==0)break;
	int i,j;
	tag=0;
	int a[n+1][3];//迷宫
	for(i=1;i<=n;i++)
		for(j=0;j<3;j++)
			cin>> a[i][j];
	cin>>m;
	DFS(1,a);//从第一层开始搜索
	if(tag==1)
		cout<<"YES"<<endl;
	else if(tag==0)
		cout<<"NO"<<endl;
	}
	return 0;
}

二、基于Dijsktra算法的最短路径求解

#include <iostream>
#include <cstring>
#define MVNum 100
#define MaxInt 999
using namespace std;
 
typedef struct
{
	char vexs[MVNum];//点集 
	int arcs[MVNum][MVNum];//边的邻接矩阵 
	int vexnum,arcnum;//点数&边数 
}AMGraph;
 
int LocateVex(AMGraph G,char u)
 {//存在则返回u在顶点表中的下标;否则返回-1
   int i;
   for(i=0;i<G.vexnum;++i)
     if(u==G.vexs[i])
       return i;
   return -1;
 }
 
void InitAM(AMGraph &G)
{//初始化图 
 	memset(G.vexs,0,sizeof(G.vexs));//初始化顶点集 
	for(int i=0;i<MVNum;i++)
		for(int j=0;j<MVNum;j++)
			G.arcs[i][j]=MaxInt;
	return;
}
 
int CreateUDN(AMGraph &G)
{
	int i,j,k;  
	//G.vexnum++;
	for(i=0;i<G.vexnum;i++)
		cin>>G.vexs[i];
	for(k=0;k<G.arcnum;k++)//将边录入邻接矩阵,顺便将顶点录入 
	{
		char v1,v2;int w;
		cin>>v1>>v2>>w;//边的端点
		i=LocateVex(G,v1);
		j=LocateVex(G,v2);
		G.arcs[i][j]=w;
		G.arcs[j][i]=G.arcs[i][j];
		G.arcs[i][j]=w;
		G.arcs[k][k]=0;
	}
	return 1;
}
 
void ShortestPath_DIJ(AMGraph G){ 
    //用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径 
    char v0,v1;
    int S[MVNum];
    int D[MVNum];
    int Path[MVNum];
    cin>>v0>>v1;
    int v00=LocateVex(G,v0);
    int n=G.vexnum; int v;                  		//n为G中顶点的个数 
    for( v = 0; v<n; ++v){             	//n个顶点依次初始化 
       S[v] = false;                  	//S初始为空集 
       D[v] = G.arcs[v00][v];           	//将v0到各个终点的最短路径长度初始化 
       if(D[v]< MaxInt)  Path [v]=v00; //v0和v之间有弧,将v的前驱置为v0 
       else Path [v]=-1;               	//如果v0和v之间无弧,则将v的前驱置为-1 
      }//for 
      S[v00]=true;                    	//将v0加入S 
      D[v00]=0;     
	  int w;  int i;               		//源点到源点的距离为0 	
/*―开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集―*/ 
      for(i=1;i<n; ++i){               	//对其余n?1个顶点,依次进行计算 
        int min= MaxInt;  
        for(w=0;w<n; ++w) 
          if(!S[w]&&D[w]<min)  
              {v=w; min=D[w];}         	//选择一条当前的最短路径,终点为v 
        S[v]=true;                   		//将v加入S 
        for(w=0;w<n; ++w) 	//更新从v0出发到集合V?S上所有顶点的最短路径长度 
        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   
	w=LocateVex(G,v1);
	cout<<D[w]<<endl; 
	char road[G.vexnum];
	road[0]=G.vexs[w];
	int t=w;i=0;
	while(1)
	{  
		i++;
		if(t==-1||t==v00)break;
		//cout<<G.vexs[Path[t]];//<<"#"<<Path[t]<<"#"<<Path[Path[t]]
		road[i]=G.vexs[Path[t]];
		//if(t!=-1||t!=v00)cout<<" ";
		t=Path[t];	
	}
	while(i)
	{
		if(road[i])cout<<road[i]<<" ";
		i--;
	} 
	cout<<road[0];
	cout<<endl;
}//ShortestPath_DIJ 
 
void CA(AMGraph &G)
{//输出矩阵 
	int i;int j;
	//输出表头 
	cout<<0<<" ";
	for(int i=0,j;i<G.vexnum;i++)
	{
			cout<<G.vexs[i];
			if(i!=G.vexnum-1)cout<<" ";
	}
	cout<<endl;
	for(i=0;i<G.vexnum;i++)
	{
		//输出表头 
		cout<<G.vexs[i];
		if(i!=G.vexnum)cout<<" ";
		//输出内容 
		for(j=0;j<G.vexnum;j++)
		{
			cout<<G.arcs[i][j];
			if(j!=G.vexnum-1)cout<<" "; 
		}
		cout<<endl;
	}
 } 
 
int main()
{	
	while(1)
	{
		AMGraph G;
		InitAM(G);
		cin>>G.vexnum>>G.arcnum;
		if(G.vexnum==0&&G.arcnum==0)break;
		CreateUDN(G);
		//CA(G);
		ShortestPath_DIJ(G);
		//cout<<"--------------"<<endl;
	}
}

三、六度空间理论

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXN 10005

typedef struct VNode* Vertex;
struct VNode {
	Vertex Next;
	int V;
};

typedef struct LNode {
	Vertex FirstEdge;
	
}List[MAXN];

typedef struct GNode* Graph;
struct GNode {
	int Nv,Ne;
	List Head;
};

Graph G;


void Insert(int v,int w) {
	Vertex NewNode = (Vertex)malloc(sizeof(struct VNode));
	NewNode->V = v;
	NewNode->Next = G->Head[w].FirstEdge;
	G->Head[w].FirstEdge = NewNode;
	
	NewNode = (Vertex) malloc(sizeof(struct VNode));
	NewNode->V = w;
	NewNode->Next = G->Head[v].FirstEdge;
	G->Head[v].FirstEdge = NewNode;
}

int visit[MAXN];

void BFS(int s) {
	int Q[MAXN],front = 0,rear = 0,v,i;
	int tail,last = s,cnt = 0,level = 0,kase = s;
	Vertex p;
	double perc;
	Q[++rear] = s;
	visit[s] = 1;
	cnt ++;
	while(rear!=front) {
		v = Q[++front];
		for(p = G->Head[v].FirstEdge;p;p = p->Next) {
			if(!visit[p->V]) {
				Q[++rear] = p->V;
				visit[p->V] =1;
				cnt ++;
				tail = p->V;
			}
		}
		if(v==last) {
			level ++;
			last = tail;
		}
		if(level == 6) break;
	}
	perc = ((double)cnt)/((double)G->Nv) * 100;
	printf("%d: %.2lf%%\n",kase,perc);
}
int main()
{
	int i;
	int v,w;
	G = (Graph)malloc(sizeof(struct GNode));
	while(1){
	scanf("%d%d",&G->Nv,&G->Ne);
	if(!G->Nv||!G->Ne)
		return 0;
	for(i=1;i<=G->Nv;i++)
		G->Head[i].FirstEdge = NULL;
	for(i=1;i<=G->Ne;i++) {
		scanf("%d%d",&v,&w);
		Insert(v,w);
	}
	for(i=1;i<=G->Nv;i++) {
		memset(visit,0,sizeof(visit));
		BFS(i);
	}
	}
	return 0;
	
}

四、基于邻接表的新顶点的增加

#include<iostream>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MVNum 100
using namespace std;

typedef struct VNode{
	int data;
	struct VNode *next;
}VNode,*NodeList;

typedef struct{
	NodeList V[MVNum];
	int vexnum,arcnum;
}ALGragh ;

int CreateUDG(ALGragh  &G,int vexnum,int arcnum){
	G.vexnum = vexnum;
	G.arcnum = arcnum;
	for(int i=1;i<=vexnum; i ++){
		G.V[i] = new VNode;
		G.V[i]->next = NULL;
		G.V[i]->data = i;
	}
    for(int i=0;i<arcnum;i++){
		int v1,v2;
		cin>>v1>>v2;
		NodeList p1 =new VNode;
		p1->data =v2;
		p1->next =G.V[v1]->next;
		G.V[v1]->next = p1;
		NodeList p2 =new VNode;
		p2->data = v1;
		p2->next = G.V[v2]->next;
		G.V[v2]->next = p2;
	}
	return OK;
}

int InsertVex(ALGragh  &G){
	int data;
	cin>>data;
	G.vexnum++;
	G.V[G.vexnum] = new VNode;
    G.V[G.vexnum]->data = data;
    G.V[G.vexnum]->next = NULL;
    return OK;
}

int PrintGraph(ALGragh  G){
	for(int i=1;i<=G.vexnum;i++){
		NodeList p =G.V[i];
		while(p->next){
			cout<<p->data<<" ";
			p = p->next;
		}
		cout<<p->data<<endl;
	}
	return OK;
}



int main()
{
	int n,m;
	while(cin>>n>>m)
	{
      	if(n==0&&m==0) break;     //输入结束标志
      	ALGragh G;
       	CreateUDG(G,n,m);      //采用邻接表表示法,创建无向图G
     	InsertVex(G);        //在图G中增添新顶点
	   	PrintGraph(G);      //输出图G
	}
	return 0;
}

五、基于邻接矩阵的新顶点的增加

#include <iostream>
#define MaxInt 32767 
#define MVNum 100
#define OK 1
#define ERROR -1
using namespace std;
 
typedef struct{
	char vexs[MVNum];
	int arcs[MVNum][MVNum];
	int vexnum,arcnum;
}AMGraph;
 
int InitAM(AMGraph &G){
    for(int i =0;i<MVNum; i++)
      G.vexs[i] = 0;
    for(int i =0;i<MVNum; i++)
     for(int j =0 ; j<MVNum;j++){
	 	G.arcs[i][j]= 0;
	}
	return OK;
}
 
int LocateVex(AMGraph G,char v){
	for(int i=0;i<G.vexnum;i++)
	 if(v==G.vexs[i])
	   return i;
	return ERROR;
}
 
int CreateUDN(AMGraph &G){
	int n;
	int vex = 0;
	for(n=0;n<G.arcnum;n++){
		char v1,v2;
		cin>>v1>>v2;
		int tag = 0;
		for(int i =0;i<G.vexnum;i++){
			if(v1==G.vexs[i]) tag = 1;
		}
		if(tag == 0){
			G.vexs[vex] = v1;
			vex++;
		}
		tag = 0;
		for(int i =0;i<G.vexnum;i++){
			if(v2==G.vexs[i]) tag = 1;
		}
		if(tag == 0){
			G.vexs[vex] = v2;
			vex++;
		}
		int i = LocateVex(G,v1);
		int j = LocateVex(G,v2);
		G.arcs[i][j] = 1;
		G.arcs[j][i] = G.arcs[i][j]; 
	}
	cin>>G.vexs[vex];
    G.vexnum++;
	return OK; 
}
void PrintAM(AMGraph &G){
	int i,j;
	cout<<0<<" ";
	for(i=0;i<G.vexnum;i++)
	{
			cout<<G.vexs[i];
			if(i!=G.vexnum-1)
			  cout<<" ";
	}
	cout<<endl;
	for(i=0;i<G.vexnum;i++)
	{
		cout<<G.vexs[i]; //输出表头 
		if(i!=G.vexnum)
		   cout<<" ";
		//输出内容 
		for(j=0;j<G.vexnum;j++)
		{
			cout<<G.arcs[i][j];
			if(j!=G.vexnum-1)
			  cout<<" "; 
		}
		cout<<endl;
	}
 } 
 int main()
{	
    AMGraph G;
	while(cin>>G.vexnum>>G.arcnum&&G.vexnum!=0&&G.arcnum!=0)
	{	InitAM(G);
		CreateUDN(G);
		PrintAM(G); 	
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三木几

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值