华为机试之广度优先遍历

来源:互联网 发布:windows xp pe u盘版 编辑:程序博客网 时间:2024/05/18 00:56

在华为的论坛上看到了下面这个题目,想着最近刚好没事,就来写一下。

编译环境:VS2005


高级题:地铁换乘

已知2条地铁线路,其中A为环线,B为东西向线路,线路都是双向的。经过的站点名分别如下,两条线交叉的换乘点用T1、T2表示。编写程序,任意输入两个站点名称,输出乘坐地铁最少需要经过的车站数量(含输入的起点和终点,换乘站点只计算一次)。
地铁线A(环线)经过车站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18
地铁线A(直线)经过车站:B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B10 T2 B11 B12 B13 B14 B15

输入:输入两个不同的站名

输出:输出最少经过的站数,含输入的起点和终点,换乘站点只计算一次


刚开始看到这道题的时候,感觉是用链表,但具体怎么写不会

参考了别人的程序,具体思路是先用邻接表建立无向图,然后广度优先遍历

之前学数据结构的时候,只是明确了排序、链表、查找、图等基本概念,具体如何用程序实现则没有涉及

这里有2个基本数据结构,边表edgenode和顶点表vernode

顶点表指各链表的第一个

链表中除第一个其他是边表

左图为环线A线,右图为直线B线,其中9为换乘站T1,14为换乘站T2



广度优先遍历:

这里我们需要用到队列queue,需要include<queue>

1.指定起点A2和终点A4

2.若顶点A2不在队列中,则将顶点A2压入队列

3.将顶点A2弹出队列前,先检查该顶点A2是不是终点,若是,则break;若不是,则将该顶点A2的下一层的顶点(A3和A1)压入队列,然后把该顶点A2弹出队列。当将下一层的顶点压入队列时,计数值加1,这样我们就可以得到下一层该检查的顶点数(在此例中是2)

4.检查该层的顶点是否都检查完,若没检查完,则继续第3步;若检查完了,则开始下一层的检查

下图为简易思路:



下面给出实现代码:

#include <vector>#include <iostream>#include <conio.h>#include <string.h>#include <queue>using namespace std;#define MAX 35 #define SUBWAY_A 20#define SUBWAY_B 15typedef struct node{//边表int  adjvex;struct node *next;}edgenode;typedef struct{//顶点表int data;edgenode *first;char name[5];char visit_flag;}vernode;const char subway_name1[SUBWAY_A][5]={"A1","A2","A3","A4","A5","A6","A7","A8","A9","T1","A10","A11","A12","A13","T2","A14","A15","A16","A17","A18"};const char subway_name2[SUBWAY_B][5]={"B1","B2","B3","B4","B5","B6","B7","B8","B9","B10","B11","B12","B13","B14","B15"};vernode ga[MAX];/*函数输入:vernode ga[]顶点表函数输出:无函数功能:用邻接表表示图*/void creat(vernode ga[]){edgenode *p; //初始化for(int i=0;i<MAX;i++){ga[i].first = NULL;ga[i].visit_flag = 0;//未入列if(i<=19)strcpy(ga[i].name,subway_name1[i]);elsestrcpy(ga[i].name,subway_name2[i-SUBWAY_A]);}//建立A地铁图for(int i=1;i<=SUBWAY_A-2;i++){ga[i].data = i;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = i-1;p->next = ga[i].first;ga[i].first = p;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = i+1;p->next = ga[i].first;ga[i].first = p;}//0顶点ga[0].data = 0;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 19;p->next = ga[0].first;ga[0].first = p;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 1;p->next = ga[0].first;ga[0].first = p;//19顶点ga[19].data = 19;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 18;p->next = ga[19].first;ga[19].first = p;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 0;p->next = ga[19].first;ga[19].first = p;//9 T1换乘站p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 24;p->next = ga[9].first;ga[9].first = p;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 25;p->next = ga[9].first;ga[9].first = p;//14 T2换乘站p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 29;p->next = ga[14].first;ga[14].first = p;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 30;p->next = ga[14].first;ga[14].first = p;//建立B地铁图for(int i=1+SUBWAY_A;i<=33;i++){if((i==24)|(i==25)|(i==29)|(i==30))continue;ga[i].data = i;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = i-1;p->next = ga[i].first;ga[i].first = p;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = i+1;p->next = ga[i].first;ga[i].first = p;}//24顶点连接9 T1ga[24].data = 24;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 23;p->next = ga[24].first;ga[24].first = p;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 9;p->next = ga[24].first;ga[24].first = p;//25顶点连接9 T1ga[25].data = 25;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 26;p->next = ga[25].first;ga[25].first = p;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 9;p->next = ga[25].first;ga[25].first = p;//29顶点连接14 T2ga[29].data = 29;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 28;p->next = ga[29].first;ga[29].first = p;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 14;p->next = ga[29].first;ga[29].first = p;//30顶点连接14 T2ga[30].data = 30;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 31;p->next = ga[30].first;ga[30].first = p;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 14;p->next = ga[30].first;ga[30].first = p;//20端点连接21ga[20].data = 20;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 21;p->next = ga[20].first;ga[20].first = p;//34端点连接33ga[34].data = 34;p = (edgenode*)malloc(sizeof(edgenode));p->adjvex = 33;p->next = ga[34].first;ga[34].first = p;edgenode *s;//打印显示线路图for(int i=0;i<MAX;i++){//cout << ga[i].data;cout << ga[i].name;s = ga[i].first;while(s!=NULL){cout << "->" << ga[s->adjvex].name;s = s->next;}cout << endl;}}/*函数功能:对建立好的图进行广度优先遍历函数输入输出:无*/void Get_SUBWAY_LINE(){char str[2][5];int start_i;cout <<"*************************************\n请输入起点与终点:";while(scanf("%s %s",str[0],str[1])!=EOF)//输入两个站{char find_flag = 0;int count=0,num=0,temp_num=1;edgenode *s;queue<vernode>q;for(int i=0;i<MAX;i++){ga[i].visit_flag = 0;//未入列}for(int i=0;i<MAX;i++)if(!strcmp(str[0],ga[i].name)){start_i = i;break;}if(!ga[start_i].visit_flag)//未入列则入列{q.push(ga[start_i]);ga[start_i].visit_flag = 1;}while(!q.empty())//寻找路径{if(find_flag){cout << "共需经过"<<count<<"站\n*************************************\n\n";cout <<"*************************************\n请输入起点与终点:";break;//找到路径}count++;cout << "****第" << count <<"次搜索****"<<endl;for(int i=0;i<temp_num;i++)//取出同一层的各站点比对{//查看队列头是否为终点,若是,breakcout << q.front().name<<"  ";if(!strcmp(str[1],q.front().name))//找到终点站{find_flag = 1;break;}//队列头若不是终点,将它的下一层加入到队列中,并将它弹出s = q.front().first;while(s!=NULL)//将下一层的广度都送入队列{if(!ga[s->adjvex].visit_flag){q.push(ga[s->adjvex]);num++;ga[s->adjvex].visit_flag = 1;}s = s->next;}q.pop();}//fortemp_num = num;num = 0;cout << endl;}//while(!q.empty())}//while}void main(){creat(ga);Get_SUBWAY_LINE();}




0 0