读书人

关于邻接图的有关问题

发布时间: 2013-01-21 10:15:38 作者: rapoo

关于邻接图的问题
求大大帮忙看下代码,在运行到输入边的时候会自动跳过输入环节直接跳到深度遍历。。。然后。。。。就出错了。。我想知道哪里出问题了。
关于邻接图的有关问题
#include"stdio.h"
#include"stdlib.h"
#define MaxVertexNum 50 //定义最大顶点数
typedef struct node{ //边表结点
int adjvex; //邻接点域
struct node *next; //链域
}EdgeNode;
typedef struct vnode{ //顶点表结点
char vertex; //顶点域
EdgeNode *firstedge; //边表头指针
}VertexNode;
typedef VertexNode AdjList[MaxVertexNum]; //AdjList是邻接表类型
typedef struct {
AdjList adjlist; //邻接表
int n,e; //图中当前顶点数和边数
} ALGraph; //图类型
//建立图的邻接表
void CreatALGraph(ALGraph *G)
{
int i,j,k;
char a;
EdgeNode *s; //定义边表结点
printf("输入顶点数和边数: ");
scanf("%d,%d",&G->n,&G->e); //读入顶点数和边数
//scanf("%c",&a);
//we=G->e;
printf("输入顶点字节:");
for(i=0;i<G->n;i++) //建立边表
{
scanf("%s",& G->adjlist[i].vertex/*a*/);
// =a; //读入顶点信息
// G->adjlist[i].firstedge=NULL; //边表置为空表
}
printf("输入边创造图表:\n");
for(k=0;k<G->e;k++) { //建立边表
scanf("%d%d",&i,&j); //读入边(Vi,Vj)的顶点对序号
s=(EdgeNode *)malloc(sizeof(EdgeNode)); //生成边表结点
s->adjvex=j; //邻接点序号为j
s->next=G->adjlist[i].firstedge;

s=(EdgeNode *)malloc(sizeof(EdgeNode));
G->adjlist[i].firstedge=s; //将新结点*S插入顶点Vi的边表头部
s->adjvex=i; //邻接点序号为i
s->next=G->adjlist[j].firstedge;
G->adjlist[j].firstedge=s; //将新结点*S插入顶点Vj的边表头部
}
}
//定义标志向量,为全局变量
typedef enum{FALSE,TRUE} Boolean;
Boolean visited[MaxVertexNum];
//DFS:深度优先遍历的递归算法
void DFSM(ALGraph *G,int i)
{ //以Vi为出发点对邻接链表表示的图G进行DFS搜索


EdgeNode *p;
printf("%c",G->adjlist[i].vertex); //访问顶点Vi
visited[i]=TRUE; //标记Vi已访问
p=G->adjlist[i].firstedge; //取Vi边表的头指针
while(p) { //依次搜索Vi的邻接点Vj,这里j=p->adjvex
if(! visited[p->adjvex]) //若Vj尚未被访问
DFSM(G,p->adjvex); //则以Vj为出发点向纵深搜索
p=p->next; //找Vi的下一个邻接点
}
}
void DFS(ALGraph *G)
{
int i;
for(i=0;i<G->n;i++)
visited[i]=FALSE; //标志向量初始化
for(i=0;i<G->n;i++)
if(!visited[i]) //Vi未访问过
DFSM(G,i); //以Vi为源点开始DFS搜索
}
//BFS:广度优先遍历
void BFS(ALGraph *G,int k)
{ //以Vk为源点对用邻接链表表示的图G进行广度优先搜索
int i,f=0,r=0;
EdgeNode *p;
int cq[MaxVertexNum]; //定义FIFO队列
for(i=0;i<G->n;i++)
visited[i]=FALSE; //标志向量初始化
for(i=0;i<=G->n;i++)
cq[i]=-1; //初始化标志向量
printf("%c",G->adjlist[k].vertex);//访问源点Vk
visited[k]=TRUE;
cq[r]=k; //Vk已访问,将其入队。注意,实际上是将其序号入队
while(cq[f]!=-1) { // 队列非空则执行
i=cq[f];f=f+1; //Vi出队
p=G->adjlist[i].firstedge; //取Vi的边表头指针
while(p) { //依次搜索Vi的邻接点Vj(令p->adjvex=j)
if(!visited[p->adjvex]) { //若Vj未访问过
printf("%c",G->adjlist[p->adjvex].vertex); //访问Vj
visited[p->adjvex]=TRUE;
r=r+1;cq[r]=p->adjvex; //访问过的Vj入队


}
p=p->next; //找Vi的下一个邻接点
}
}//endwhile
}
//主函数
void main()
{

int i;
ALGraph *G;
G=(ALGraph *)malloc(sizeof(ALGraph));
CreatALGraph(G);
printf("深度遍历: ");
DFS(G);
printf("\n");
printf("广度遍历: ");
BFS(G,3);
printf("\n");
}
[解决办法]
lz你输入的格式就不对,应该是6,12 你看你的程序就明白了,然后调试一下看是否有问题。
[解决办法]

引用:
Quote: 引用:

引用:lz你输入的格式就不对,应该是6,12 你看你的程序就明白了,然后调试一下看是否有问题。
还是有问题。。。在进行到深度遍历的时候又停止了。。。。

调试一下不知道什么原因造成的吗?
[解决办法]
这个代码不是你自己写的吧
图遍历都不输入边,怎么建图.
[解决办法]
你这是有向图?
你的代码有2个问题
1.在初始化图的顶点时,该顶点的邻接边应该初始化为空,
这直接导致你在bfs和dfs时,while(p)这个判断没有意义。
应该做如下更改。
printf("输入顶点字节:");
for(i=0;i<G->n;i++) //建立边表
{
scanf("%s",& G->adjlist[i].vertex/*a*/);
// =a; //读入顶点信息
G->adjlist[i].firstedge=NULL; //边表置为空表
}

2.根据你建图的注释说明你对邻接表理解错误,直接导致你建立邻接表错误。
邻接表以每个顶点为链表的头节点,与该结点相邻的顶点插入链表中。
所以应该做如下更改:

printf("输入边创造图表:\n");
for(k=0;k<G->e;k++)
{ //建立边表
scanf("%d%d",&i,&j); //读入边(Vi,Vj)的顶点对序号
s=(EdgeNode *)malloc(sizeof(EdgeNode)); //生成边表结点
s->adjvex=j; //邻接点序号为j
s->next=G->adjlist[i].firstedge;
G->adjlist[i].firstedge=s; //将新邻接点插入顶点Vi的边表头部
}


改完之后
#include"stdio.h"
#include"stdlib.h"
#define MaxVertexNum 50 //定义最大顶点数
typedef struct node{ //边表结点
int adjvex; //邻接点域
struct node *next; //链域
}EdgeNode;
typedef struct vnode{ //顶点表结点
char vertex; //顶点域
EdgeNode *firstedge; //边表头指针
}VertexNode;
typedef VertexNode AdjList[MaxVertexNum]; //AdjList是邻接表类型
typedef struct {
AdjList adjlist; //邻接表
int n,e; //图中当前顶点数和边数
} ALGraph; //图类型


//建立图的邻接表
void CreatALGraph(ALGraph *G)
{
int i,j,k;
char a;
EdgeNode *s; //定义边表结点
printf("输入顶点数和边数: ");
scanf("%d%d",&G->n,&G->e); //读入顶点数和边数
//scanf("%c",&a);
//we=G->e;
printf("输入顶点字节:");
for(i=0;i<G->n;i++) //建立边表
{
scanf("%s",& G->adjlist[i].vertex/*a*/);
// =a; //读入顶点信息
G->adjlist[i].firstedge=NULL; //边表置为空表
}
printf("输入边创造图表:\n");
for(k=0;k<G->e;k++)
{ //建立边表
scanf("%d%d",&i,&j); //读入边(Vi,Vj)的顶点对序号
s=(EdgeNode *)malloc(sizeof(EdgeNode)); //生成边表结点
s->adjvex=j; //邻接点序号为j
s->next=G->adjlist[i].firstedge;
G->adjlist[i].firstedge=s; //将新邻接点插入顶点Vi的边表头部
}
}
//定义标志向量,为全局变量
typedef enum{FALSE,TRUE} Boolean;
Boolean visited[MaxVertexNum];
//DFS:深度优先遍历的递归算法
void DFSM(ALGraph *G,int i)
{ //以Vi为出发点对邻接链表表示的图G进行DFS搜索
EdgeNode *p;
printf("%c",G->adjlist[i].vertex); //访问顶点Vi
visited[i]=TRUE; //标记Vi已访问
p=G->adjlist[i].firstedge; //取Vi边表的头指针
while(p) { //依次搜索Vi的邻接点Vj,这里j=p->adjvex
if(! visited[p->adjvex]) //若Vj尚未被访问
DFSM(G,p->adjvex); //则以Vj为出发点向纵深搜索
p=p->next; //找Vi的下一个邻接点
}
}
void DFS(ALGraph *G)
{
int i;
for(i=0;i<G->n;i++)
visited[i]=FALSE; //标志向量初始化
for(i=0;i<G->n;i++)
if(!visited[i]) //Vi未访问过
DFSM(G,i); //以Vi为源点开始DFS搜索
}
//BFS:广度优先遍历
void BFS(ALGraph *G,int k)
{ //以Vk为源点对用邻接链表表示的图G进行广度优先搜索
int i,f=0,r=0;
EdgeNode *p;
int cq[MaxVertexNum]; //定义FIFO队列
for(i=0;i<G->n;i++)
visited[i]=FALSE; //标志向量初始化
for(i=0;i<=G->n;i++)
cq[i]=-1; //初始化标志向量
printf("%c",G->adjlist[k].vertex);//访问源点Vk
visited[k]=TRUE;
cq[r]=k; //Vk已访问,将其入队。注意,实际上是将其序号入队
while(cq[f]!=-1) { // 队列非空则执行
i=cq[f];f=f+1; //Vi出队
p=G->adjlist[i].firstedge; //取Vi的边表头指针
while(p) { //依次搜索Vi的邻接点Vj(令p->adjvex=j)


if(!visited[p->adjvex]) { //若Vj未访问过
printf("%c",G->adjlist[p->adjvex].vertex); //访问Vj
visited[p->adjvex]=TRUE;
r=r+1;cq[r]=p->adjvex; //访问过的Vj入队
}
p=p->next; //找Vi的下一个邻接点
}
}//endwhile
}
//主函数
void main()
{

int i;
ALGraph *G;
G=(ALGraph *)malloc(sizeof(ALGraph));
CreatALGraph(G);
printf("深度遍历: ");
DFS(G);
printf("\n");
printf("广度遍历: ");
BFS(G,3);
system("pause");
printf("\n");
}



另外图的遍历不建议使用递归的方式进行,递归效率低而且容易爆栈。
[解决办法]
参考boost.graph?
[解决办法]
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。

读书人网 >C++

热点推荐