首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

关于邻接图的有关问题

2013-01-21 
关于邻接图的问题求大大帮忙看下代码,在运行到输入边的时候会自动跳过输入环节直接跳到深度遍历。。。然后。。。

关于邻接图的问题
求大大帮忙看下代码,在运行到输入边的时候会自动跳过输入环节直接跳到深度遍历。。。然后。。。。就出错了。。我想知道哪里出问题了。
关于邻接图的有关问题
#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里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。

热点排行