BFS--点到点间的最短路径

来源:互联网 发布:mac打开照片 编辑:程序博客网 时间:2024/05/22 01:35
# include <stdio.h># include <malloc.h># include <memory.h># define MAX 20//最大顶点数 typedef struct ARCNODE{int num;//该边所指的顶点的位置 struct ARCNODE * next;//指向下一条边的指针 }arcnode; //表的结点 typedef struct Vnode{char data;//顶点信息 arcnode * firstarc;//指向第一条依附该顶点的边的弧指针 }VNODE,adjvex[MAX];//头结点 typedef struct {adjvex vertices;bool visited[MAX];//访问标志数组 int arcnum,vexnum;//图的当前结点数和弧数 }mgraph;typedef struct Qnode{char data;struct Qnode * pre;struct Qnode * next;}qnode,*queueptr;//创建队列结点 typedef struct{queueptr front;//队头指针 queueptr rear;//队尾指针 }linkqueue;//创建队列 void initqueue(linkqueue *q)//初始化队列 {q->front = (queueptr)malloc(sizeof(qnode));//队头队尾指向头结点 if (!q->front){printf ("无效图\n");//分配失败 }else{q->front->next = NULL;q->rear = q->front;}}void Enqueue(linkqueue *q,char value)//入队函数 {queueptr newp = (queueptr)malloc(sizeof(qnode));if (!newp){printf ("无效图\n");}newp->data = value;newp->next = NULL;q->rear->next = newp;//p插入原对尾 q->rear = newp;//p成为新的队尾 }void init_mgraph(mgraph &g)//初始化图 {memset(g.visited,false,sizeof(bool)*MAX);//访问标志数组置false,表示未访问 g.vexnum = 0;g.arcnum = 0;}int locatevex(mgraph &g,char ch)//定位顶点ch在顶点向量中的位置 {int i;for (i=0; i<g.vexnum && ch != g.vertices[i].data; ++i);if (i>=g.vexnum)return -1;return i;}void add_vex(mgraph &g)//增加节点 {printf ("请输入顶点个数\n");scanf ("%d",&g.vexnum);printf ("请输入顶点信息\n");for (int i=0; i<g.vexnum; ++i){scanf (" %c",&g.vertices[i].data);//构造顶点向量 g.vertices[i].firstarc = NULL;} }void add_arc(mgraph &g)//增加边 {arcnode *s,*p,*t;printf ("请输入边的个数\n");scanf ("%d",&g.arcnum);char ch1,ch2;printf ("请输入边的信息\n");for (int k=0; k<g.arcnum; ++k){scanf (" %c %c",&ch1,&ch2);int i = locatevex(g,ch1);int j = locatevex(g,ch2);//确定ch1,ch2在图中的位置 s = (arcnode *)malloc(sizeof(ARCNODE));t = (arcnode *)malloc(sizeof(ARCNODE));s->num = j;//该边所指向的顶点的位置为j s->next = NULL;if (!g.vertices[i].firstarc){g.vertices[i].firstarc = s;}else{for (p=g.vertices[i].firstarc; p->next; p=p->next);p->next = s;}t->num = i;//该边所指向的顶点的位置为i t->next = NULL;if (!g.vertices[j].firstarc){g.vertices[j].firstarc = t;}else{for (p=g.vertices[j].firstarc; p->next; p=p->next);p->next = t;}}}void creat_mgraph(mgraph &g)//构造邻接链表 {add_vex(g);add_arc(g);}void print_mgraph(mgraph &g){int i;arcnode *p;printf ("编号顶点邻点编号\n");for (i=0; i<g.vexnum; ++i){printf (" %d%c",i,g.vertices[i].data);for (p=g.vertices[i].firstarc; p;p=p->next){printf ("%d ",p->num);}printf ("\n");}}void path_mgraph(mgraph &g,char ch1,char ch2,char path[])//求点到点的最短路径 {//从第i个顶点开始搜索 arcnode *p;int i = locatevex(g,ch1);int s = locatevex(g,ch2);int found = 0;char gettop;int top;linkqueue *q = (linkqueue *)malloc(sizeof(linkqueue));initqueue(q);//初始化队列 g.visited[i] = true;//处理源点 Enqueue(q,g.vertices[i].data);//源点入队 q->rear->pre = q->front;//第一个结点的前驱指针指向front queueptr temp = q->front->next;//处理队列中的每个顶点 while(!found){gettop = temp->data;top = locatevex(g,gettop);for (p=g.vertices[top].firstarc; p && !found; p=p->next){if (s == p->num)//找到目标点 {found = 1;//标志设为1,入队列,退出 Enqueue(q,g.vertices[p->num].data);q->rear->pre = temp;//加入队列中的点,前驱指针指向它的源点 }else if (!g.visited[p->num])//如果不是,就访问,并加入队列 {g.visited[p->num] = true;Enqueue(q,g.vertices[p->num].data);//入队 q->rear->pre = temp;}}temp = temp->next;}int j=0;for (temp=q->rear; temp != q->front; temp=temp->pre)//复制队列中的顶点到字符串中去 {path[j++] = temp->data;}path[j] = '\0';}int main (void){mgraph g;init_mgraph(g);creat_mgraph(g);print_mgraph(g);char ch1,ch2;char *path;path = (char *)malloc(sizeof(char)*MAX);printf ("请输入两个位置\n");scanf (" %c %c",&ch1,&ch2);path_mgraph(g,ch1,ch2,path);//广度优先搜索 int i=0;while(path[i]){printf ("%c ",path[i++]);//输出路径 }printf ("\n");}

0 0
原创粉丝点击