数据结构——广度优先搜索求点到点的最短路径

#include <iostream>
using namespace std;

#include
<stdio.h>
#include
<stdlib.h>

#define OK 1
#define NULL 0
#define MAX_VERTEX_NUM 20 // 最大顶点数

typedef
char VertexType;
typedef
int VRType;
typedef
int InforType;

typedef
struct ArcNode
{
int adjvex; //该边所指的顶点的位置
struct ArcNode *nextarc; //指向下一条边的指针
//int weight; //边的权
}ArcNode; //表的结点

typedef
struct VNode
{
VertexType data;
//顶点信息(如数据等)
ArcNode *firstarc; //指向第一条依附该顶点的边的弧指针
}VNode, AdjList[MAX_VERTEX_NUM]; //头结点

typedef
struct ALGraph
{
AdjList vertices;
int visited[MAX_VERTEX_NUM]; //访问标志数组
int vexnum, arcnum; //图的当前顶点数和弧数
}ALGraph;

//==============================================================================
typedef struct qnode
{
char data;
struct qnode * pre;
struct qnode * next;
}Qnode,
* Queueptr; // 创建链 Qnode是struct qnode的别名,Queueptr是struct qnode *的别名
typedef struct
{
Queueptr front;
//对头指针
Queueptr rear; //队尾指针
}LinkQueue; //创建队列

//初始化队列
void InitQueue(LinkQueue *Q)
{
Q
->front=(Queueptr) malloc(sizeof(Qnode)); //队头和队尾指向头结点
if(!Q->front)
{
cout
<<"no memory avaliable"<<endl; //存储分配失败
}
else
{
Q
->front->next=NULL;
Q
->rear=Q->front;
}
}

//入队列函数
void Enqueue(LinkQueue *Q,int value)
{
Queueptr newp
=(Queueptr)malloc(sizeof(Qnode));
if(!newp)
cout
<<"no memory avaliable"<<endl; //存储分配失败
newp->data=value;
newp
->next=NULL;
Q
->rear->next=newp; //p插入原队尾
Q->rear=newp; //p成为新的队尾
}
//================================================================================

//初始化图
void init_ALGraph(ALGraph &g)
{
for(int i=0;i<MAX_VERTEX_NUM;i++)
g.visited[i]
=0; //访问标志数组置0,表示没有被访问
g.vexnum=0;
g.arcnum
=0;
}
//返回顶点v在顶点向量中的位置
int LocateVex(ALGraph &G, char v)
{
int i;
for(i = 0; v != G.vertices[i].data && i < G.vexnum; i++)
;
if(i >= G.vexnum)
return -1;
return i;
}

//增加节点
void add_vex(ALGraph &G)
{
cout
<<"输入无向图顶点数: "<<endl;
cin
>>G.vexnum;
//getchar(); //吃回车
cout<<"输入顶点信息:"<<endl;
for(int i = 0; i < G.vexnum; i++)
{
cin
>>G.vertices[i].data; //构造顶点向量
G.vertices[i].firstarc = NULL;
//getchar();
}
}

//增加边
void add_arc(ALGraph &G)
{
ArcNode
*s, *t;
ArcNode
*p;

cout
<<"输入无向图边数: "<<endl;
cin
>>G.arcnum;
char v1, v2;
cout
<<"输入边信息:"<<endl;
for(int k = 0; k < G.arcnum; k++)
{
cin
>>v1>>v2;
int i = LocateVex(G, v1);
int j = LocateVex(G, v2); //确定v1 , v2在G中的位置

s
= (ArcNode*) malloc (sizeof(ArcNode));
t
= (ArcNode*) malloc (sizeof(ArcNode));

s
->adjvex = j; //该边所指向的顶点的位置为j
s->nextarc = NULL;
if(!G.vertices[i].firstarc)
{
G.vertices[i].firstarc
=s;
}
else
{
for(p = G.vertices[i].firstarc; p->nextarc; p = p->nextarc)
;
p
->nextarc=s;
}

t
->adjvex = i; //该边所指向的顶点的位置为j
t->nextarc = NULL;
if(!G.vertices[j].firstarc)
{
G.vertices[j].firstarc
=t;
}
else
{
for(p = G.vertices[j].firstarc; p->nextarc; p = p->nextarc)
;
p
->nextarc=t;
}
}
}

//构造邻接链表
void CreateUDN(ALGraph &G)
{
add_vex(G);
//增加节点
add_arc(G); //增加边
}


void PrintAdjList(ALGraph &G)
{
int i;
ArcNode
*p;
cout
<<"编号 顶点 邻点编号"<<endl;

for(i = 0; i < G.vexnum; i++)
{
cout
<<" "<<i<<" "<<G.vertices[i].data<<" ";
for(p = G.vertices[i].firstarc; p; p = p->nextarc)
cout
<<p->adjvex<<" ";
cout
<<endl;
}
}

//求点到点的最短路径
void Path(ALGraph &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]
=1; //处理源点
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->nextarc)
{
if(s == p->adjvex) //找到目标点
{
found
=1; //标志设为1,入队列,退出
Enqueue(Q,g.vertices[p->adjvex].data);
Q
->rear->pre=temp; //加入队列中的点,前驱指针指向它的源点
}
else if( !g.visited[p->adjvex] ) //如果不是,就访问,并加入队列
{
g.visited[p
->adjvex]=1;
Enqueue(Q,g.vertices[p
->adjvex].data); //入队
Q->rear->pre=temp;
}
}
temp
=temp->next;
}
//while


int j=0;
for(temp=Q->rear; temp!=Q->front; temp=temp->pre) //复制队列中的顶点到字符串中去
path[j++]=temp->data;
path[j]
='\0';
}

int main()
{
ALGraph G;
init_ALGraph(G);
//初始化图
CreateUDN(G); //创建图
PrintAdjList(G); //打印图

//求点到点的最短路径
char ch1,ch2;
char *path; //存放路径
path=(char *)malloc( MAX_VERTEX_NUM*sizeof(char) );

cout
<<"please input two points:"<<endl;
cin
>>ch1>>ch2;
Path(G,ch1,ch2,path);
//广度优先搜索

int i=0;
while(path[i])
cout
<<path[i++]; //输出路径
cout<<endl;

return 0;
}

 

posted @ 2010-08-07 01:30  忧国忧铭  Views(4490)  Comments(1Edit  收藏  举报