主题:图的广度遍历
我的如存储结构为邻接表结构,队列的QElemType为图的元素
我程序错误在与图的广度遍历,输入如下:5 6 回车
a回车b回车c回车d回车e回车 ab回车ad回车bc回车be回车cd回车ce回车 输入遍历起点:b
深度遍历正常,但广度遍历打印b e c a后就死循环了,不知问题出在哪里,请大虾们请教。
不胜感激。
#include <iostream>
using namespace std;
const int MAX_VERTEX_NUM=20;
const int OK=1;
const int ERROR=-1;
const int OVERFLOW=-2;
static bool visited[MAX_VERTEX_NUM];
typedef char VertexType;//顶点的类型
typedef VertexType QElemType;
typedef enum{DG,DN,UDG,UDN}GraphKind;//{有向图0,有向网1,无向图2,无向网3}
//表结点的结构
typedef struct ArcNode{
int adjvex;//弧所指向的顶点的位置
struct ArcNode *nextarc;//指向下一条弧的指针
int *info;//该弧的相关信息的指针,如权值
}ArcNode;
//头结点的结构
typedef struct VNode{
VertexType data;//顶点信息;
ArcNode *firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
//图的结构
typedef struct{
AdjList vertices;//顶点向量
int vexnum;//图的当前顶点数
int arcnum;//图的当前弧数
int kind;//图的类型,暂时用
}ALGraph;
typedef struct QNode{
QElemType data;//类型为图顶点的类型
struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
QueuePtr front;//队头指针
QueuePtr rear;//队尾指针
}LinkQueue;
int LocateVex(ALGraph,VertexType);//查找图的顶点,返回其在顶点向量中的位置
//构造队列
int InitQueue(LinkQueue &Q){
Q.front=new QNode;
if(!Q.front) exit(OVERFLOW);
Q.rear=Q.front;
Q.front->next=NULL;
return OK;
}//InitQueue
//入列
int EnQueue(LinkQueue &Q,QElemType e){
QueuePtr p=new QNode;
if(!p) exit(OVERFLOW);
p->data=e;p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}//EnQueue
//出列
int DeQueue(LinkQueue &Q,QElemType &e){
QueuePtr p=new QNode;
if(!p) exit(OVERFLOW);
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
delete(p);
return OK;
}//DeQueue
//队列是否空?
int EmptyQueue(LinkQueue Q){
if(Q.front==Q.rear)
return 1;
else
return 0;
}//EmptyQueue
//构造无向图UDG
int CreateUDG(ALGraph &G){
int i,m,n;
VertexType v1,v2;
//构造顶点向量
cout<<"请输入图的顶点数和弧数:"<<endl;
cin>>G.vexnum>>G.arcnum;
cout<<"请输入"<<G.vexnum<<"个顶点"<<endl;
for(i=0;i<G.vexnum;i++){
cout<<"输入的第"<<i+1<<"个顶点是:"<<endl;
cin>>G.vertices[i].data;
G.vertices[i].firstarc=NULL;//初始化头结点的指针指向空值
}//for
//构造图上各顶点的关系——邻接表
cout<<"请输入相关联的"<<G.arcnum<<"条边。";
for(i=0;i<G.arcnum;i++){
cout<<"\n请输入第"<<i+1<<"条边所依附的顶点:";
cin>>v1>>v2;
m=LocateVex(G,v1);n=LocateVex(G,v2);
ArcNode *s1,*s2;//表结点
//s1->v2插到表结点v1后面
//s2->v1插到表结点v2后面
s1=new ArcNode; s2=new ArcNode;
s1->adjvex=n;s1->nextarc=G.vertices[m].firstarc; //开始G.vertices[m].firstarc==NULL
G.vertices[m].firstarc=s1;
s2->adjvex=m;s2->nextarc=G.vertices[n].firstarc;
G.vertices[n].firstarc=s2;
}//for
return OK;
}//CreateUDG
//查找图的顶点,返回其在顶点向量中的位置
int LocateVex(ALGraph G,VertexType v){
int i;
for(i=0;i<G.vexnum;i++){
if(G.vertices[i].data==v)
return i;
}//for
if(i==G.vexnum)
return ERROR;
}//LocateVex
//打印邻接表
void printGraph(ALGraph G){
int i;
for(i=0;i<G.vexnum;i++){
cout<<"第"<<i<<"个邻接表为:"<<G.vertices[i].data<<" ";
ArcNode *p=new ArcNode;
p=G.vertices[i].firstarc;
while(p!=NULL){
cout<<p->adjvex<<" ";
p=p->nextarc;
}//while
cout<<endl;
}//for
}//printGraph
//初始化标志数组
void InitVisited(){
for(int i=0;i<MAX_VERTEX_NUM;++i)
visited[i]=false;//初始化标志数组
}//InitVisited
//深度遍历递归算法
int DFSAL(ALGraph G,int k){
ArcNode *p;
visited[k]=true;
cout<<G.vertices[k].data<<" ";
for(p=G.vertices[k].firstarc;p;p=p->nextarc){
if(!visited[p->adjvex]) DFSAL(G,p->adjvex);
}//for
return OK;
}//DFSAL
//广度遍历非递归算法
void BFSAL(ALGraph G,int k){
int m,w;
LinkQueue Q;
InitQueue(Q);
ArcNode *p;
QElemType v;
cout<<G.vertices[k].data<<" ";
visited[k]=true;
EnQueue(Q,G.vertices[k].data);
while(!EmptyQueue(Q)){//Q不空
DeQueue(Q,v);
m=LocateVex(G,v);
p=G.vertices[m].firstarc;
while(p){//遍历p的所有邻接顶点
w=p->adjvex;
if(!visited[w]){
visited[w]=true;
cout<<G.vertices[w].data<<" ";
EnQueue(Q,G.vertices[w].data);
}//if
p=p->nextarc;
}//while
}//while
}//BFSAL
int main(){
VertexType v;
int k=-1;
ALGraph G;
CreateUDG(G);
printGraph(G);
cout<<"请输入开始遍历的顶点";
while(k==-1){
cin>>v;
k=LocateVex(G,v);
if(k==-1)
cout<<"输入错误,请重新输入开始遍历的顶点";
}//while
cout<<"从第"<<k+1<<"个元素"<<v<<"开始对图进行遍历:\n";
InitVisited();
cout<<"深度遍历结果为:"<<endl;
DFSAL(G,k);
InitVisited();
cout<<"广度遍历结果为:"<<endl;
BFSAL(G,k);
system("pause");
return OK;
}//main
我程序错误在与图的广度遍历,输入如下:5 6 回车
a回车b回车c回车d回车e回车 ab回车ad回车bc回车be回车cd回车ce回车 输入遍历起点:b
深度遍历正常,但广度遍历打印b e c a后就死循环了,不知问题出在哪里,请大虾们请教。
不胜感激。
#include <iostream>
using namespace std;
const int MAX_VERTEX_NUM=20;
const int OK=1;
const int ERROR=-1;
const int OVERFLOW=-2;
static bool visited[MAX_VERTEX_NUM];
typedef char VertexType;//顶点的类型
typedef VertexType QElemType;
typedef enum{DG,DN,UDG,UDN}GraphKind;//{有向图0,有向网1,无向图2,无向网3}
//表结点的结构
typedef struct ArcNode{
int adjvex;//弧所指向的顶点的位置
struct ArcNode *nextarc;//指向下一条弧的指针
int *info;//该弧的相关信息的指针,如权值
}ArcNode;
//头结点的结构
typedef struct VNode{
VertexType data;//顶点信息;
ArcNode *firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
//图的结构
typedef struct{
AdjList vertices;//顶点向量
int vexnum;//图的当前顶点数
int arcnum;//图的当前弧数
int kind;//图的类型,暂时用
}ALGraph;
typedef struct QNode{
QElemType data;//类型为图顶点的类型
struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
QueuePtr front;//队头指针
QueuePtr rear;//队尾指针
}LinkQueue;
int LocateVex(ALGraph,VertexType);//查找图的顶点,返回其在顶点向量中的位置
//构造队列
int InitQueue(LinkQueue &Q){
Q.front=new QNode;
if(!Q.front) exit(OVERFLOW);
Q.rear=Q.front;
Q.front->next=NULL;
return OK;
}//InitQueue
//入列
int EnQueue(LinkQueue &Q,QElemType e){
QueuePtr p=new QNode;
if(!p) exit(OVERFLOW);
p->data=e;p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}//EnQueue
//出列
int DeQueue(LinkQueue &Q,QElemType &e){
QueuePtr p=new QNode;
if(!p) exit(OVERFLOW);
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
delete(p);
return OK;
}//DeQueue
//队列是否空?
int EmptyQueue(LinkQueue Q){
if(Q.front==Q.rear)
return 1;
else
return 0;
}//EmptyQueue
//构造无向图UDG
int CreateUDG(ALGraph &G){
int i,m,n;
VertexType v1,v2;
//构造顶点向量
cout<<"请输入图的顶点数和弧数:"<<endl;
cin>>G.vexnum>>G.arcnum;
cout<<"请输入"<<G.vexnum<<"个顶点"<<endl;
for(i=0;i<G.vexnum;i++){
cout<<"输入的第"<<i+1<<"个顶点是:"<<endl;
cin>>G.vertices[i].data;
G.vertices[i].firstarc=NULL;//初始化头结点的指针指向空值
}//for
//构造图上各顶点的关系——邻接表
cout<<"请输入相关联的"<<G.arcnum<<"条边。";
for(i=0;i<G.arcnum;i++){
cout<<"\n请输入第"<<i+1<<"条边所依附的顶点:";
cin>>v1>>v2;
m=LocateVex(G,v1);n=LocateVex(G,v2);
ArcNode *s1,*s2;//表结点
//s1->v2插到表结点v1后面
//s2->v1插到表结点v2后面
s1=new ArcNode; s2=new ArcNode;
s1->adjvex=n;s1->nextarc=G.vertices[m].firstarc; //开始G.vertices[m].firstarc==NULL
G.vertices[m].firstarc=s1;
s2->adjvex=m;s2->nextarc=G.vertices[n].firstarc;
G.vertices[n].firstarc=s2;
}//for
return OK;
}//CreateUDG
//查找图的顶点,返回其在顶点向量中的位置
int LocateVex(ALGraph G,VertexType v){
int i;
for(i=0;i<G.vexnum;i++){
if(G.vertices[i].data==v)
return i;
}//for
if(i==G.vexnum)
return ERROR;
}//LocateVex
//打印邻接表
void printGraph(ALGraph G){
int i;
for(i=0;i<G.vexnum;i++){
cout<<"第"<<i<<"个邻接表为:"<<G.vertices[i].data<<" ";
ArcNode *p=new ArcNode;
p=G.vertices[i].firstarc;
while(p!=NULL){
cout<<p->adjvex<<" ";
p=p->nextarc;
}//while
cout<<endl;
}//for
}//printGraph
//初始化标志数组
void InitVisited(){
for(int i=0;i<MAX_VERTEX_NUM;++i)
visited[i]=false;//初始化标志数组
}//InitVisited
//深度遍历递归算法
int DFSAL(ALGraph G,int k){
ArcNode *p;
visited[k]=true;
cout<<G.vertices[k].data<<" ";
for(p=G.vertices[k].firstarc;p;p=p->nextarc){
if(!visited[p->adjvex]) DFSAL(G,p->adjvex);
}//for
return OK;
}//DFSAL
//广度遍历非递归算法
void BFSAL(ALGraph G,int k){
int m,w;
LinkQueue Q;
InitQueue(Q);
ArcNode *p;
QElemType v;
cout<<G.vertices[k].data<<" ";
visited[k]=true;
EnQueue(Q,G.vertices[k].data);
while(!EmptyQueue(Q)){//Q不空
DeQueue(Q,v);
m=LocateVex(G,v);
p=G.vertices[m].firstarc;
while(p){//遍历p的所有邻接顶点
w=p->adjvex;
if(!visited[w]){
visited[w]=true;
cout<<G.vertices[w].data<<" ";
EnQueue(Q,G.vertices[w].data);
}//if
p=p->nextarc;
}//while
}//while
}//BFSAL
int main(){
VertexType v;
int k=-1;
ALGraph G;
CreateUDG(G);
printGraph(G);
cout<<"请输入开始遍历的顶点";
while(k==-1){
cin>>v;
k=LocateVex(G,v);
if(k==-1)
cout<<"输入错误,请重新输入开始遍历的顶点";
}//while
cout<<"从第"<<k+1<<"个元素"<<v<<"开始对图进行遍历:\n";
InitVisited();
cout<<"深度遍历结果为:"<<endl;
DFSAL(G,k);
InitVisited();
cout<<"广度遍历结果为:"<<endl;
BFSAL(G,k);
system("pause");
return OK;
}//main