回 帖 发 新 帖 刷新版面

主题:[讨论]求教 关于图的遍历

程序是用VC++编的,只能执行n-1个节点,到第n个节点时就出错,其中构造邻接多重表的部分如下
void CreateGraph(int n,amlgraph &G)//构造邻接多重表
{
    pebox p1,p2;
    int i,j,k,m;
    int mark;
    initgraph(G,n);
    printf("请输入边的数量:");
    scanf("%d",&m);
    for(k=0;k<m;k++)
    {
        printf("请输入第%d条边的两个顶点:",k+1);
        scanf("%d%d",&i,&j);
        p1=(pebox)malloc(sizeof(ebox));
        p1->ivex=i;
        p1->jvex=j;
        p1->ilink=NULL;
        p1->jlink=NULL;
        p2=G.adjmulist[i].firstedge;
        if(p2==NULL)
            G.adjmulist[i].firstedge=p1;
        else
        {
            mark=0;
            while(mark==0)
            {
                if(p2->ivex==i && p2->ilink==NULL) mark=1;
        else if(p2->jvex==i && p2->jlink==NULL) mark=2;
                else if(p2->ivex==i) p2=p2->ilink;
                else p2=p2->jlink;
            }
            if(mark==1) p2->ilink=p1;
            else p2->jlink=p1;
        }
        p2=G.adjmulist[j].firstedge;
        if(p2==NULL)
            G.adjmulist[j].firstedge=p1;
        else
        {
            mark=0;
            while(mark==0)
            {
                [color=FF0000]if(p2->ivex==j && p2->ilink==NULL) mark=1;[/color]                else if(p2->jvex==j && p2->jlink==NULL) mark=2;
                else if(p2->ivex==j) p2=p2->ilink;
                else p2=p2->jlink;
            }
            if(mark==1) p2->ilink=p1;
            else p2->jlink=p1;
        }
    }
}
只要输入最后一个节点就出错,调试显示是if(p2->ivex==i && p2->ilink==NULL) mark=1这句出错,哪位高人指点一二

回复列表 (共17个回复)

沙发

没有人指点吗,我很急啊

板凳

你把全部程序写出来看看看

3 楼

#include "stdio.h"
#include "stdlib.h"
#include "iostream.h"
#define max 0
#define max_vertex_num 20
typedef int VRtype;
typedef enum{DG,DN,UDG,UDN} GraphKind;
typedef struct ArcCell{
    VRtype adj;//VRtype 是顶点关系类型.对无权图,用0或1表示相邻否;对带权图,则为权值类型
}ArcCell,AdjMatrix[max_vertex_num][max_vertex_num];//邻接矩阵

struct VertexType{
    char name;
    int data;
};

typedef struct{
    VertexType vexs[max_vertex_num];//顶点向量
    AdjMatrix arcs;
    int vexnum,arcnum;//图的当前顶点数和弧数
    GraphKind kind;
}MGraph;

//先对无权有向图进行操作
void CreateGraph(MGraph &g)
{
    int i,j,k;
    VertexType m,n;//两个顶点确定一条弧
    printf("顶点数和弧数:");
    scanf("%d,%d",&g.vexnum,&g.arcnum);
    printf("顶点:");
    for(i=0;i<g.vexnum;i++)
        cin>>g.vexs[i].name;
    for(;i<max_vertex_num;i++){
        g.vexs[i].name=NULL;
        g.vexs[i].data=NULL;
    }
    for(i=0;i<max_vertex_num;i++){
        for(j=0;j<max_vertex_num;j++)
            g.arcs[i][j].adj=0;
    }
    printf("弧:");
    for(i=0;i<g.arcnum;i++){
        cin>>m.name;
        cin>>n.name;
        for(j=0;j<g.vexnum;j++){
            if(m.name==g.vexs[j].name)
                break;
        }
        if(j==g.vexnum){
            printf("输入的弧尾不在顶点范围内,请重新输入\n");
            i--;
            continue;
        }
        for(k=0;k<g.vexnum;k++){
            if(n.name==g.vexs[k].name)
                break;
        }
        if(k==g.vexnum){
            printf("输入的弧头不在顶点范围内,请重新输入\n");
            i--;
            continue;
        }
        g.arcs[j][k].adj=1;
    }
    printf("图建立完毕\n");
}


int LocateVex(MGraph g,VertexType v)//返回顶点在数组中的位置
{
    int i;
    for(i=0;i<g.vexnum;i++){
        if(v.name==g.vexs[i].name)
            break;
    }
    if(i==g.vexnum)
        return(-1);//不存在
    return(i);
}


int GetVex(MGraph g,VertexType v)//返回顶点数据
{
    return(g.vexs[LocateVex(g,v)].data);
}


void PutVex(MGraph &g,VertexType v,int value)//对顶点赋值
{
    g.vexs[LocateVex(g,v)].data=value;
}

void InsertVex(MGraph &g,VertexType v)//插入顶点
{
    g.vexs[g.vexnum]=v;
    g.vexnum++;
}


void DeleteVex(MGraph &g,VertexType v)//删除顶点
{
    int i;
    for(i=0;i<g.vexnum;i++){
        if(g.arcs[LocateVex(g,v)][i].adj!=0){
            g.arcs[LocateVex(g,v)][i].adj=0;
            g.arcnum--;
        }
        if(g.arcs[i][LocateVex(g,v)].adj!=0){
            g.arcs[i][LocateVex(g,v)].adj=0;
            g.arcnum--;
        }
    }
    g.vexnum--;
    g.vexs[LocateVex(g,v)].name=NULL;
    g.vexs[LocateVex(g,v)].data=NULL;
}


4 楼


//重写print
void print(MGraph g)//打印图的邻接矩阵(列为弧尾,行为弧头)
{
    int i,j,count=0,temp[max_vertex_num];
    printf("图的邻接矩阵为:\n");
    printf("        ");
    for(i=0;i<max_vertex_num;i++){
        if(g.vexs[i].name!=NULL){
            printf("%c  ",g.vexs[i].name);
            temp[count]=i;
            count++;
        }
    }
    printf("\n");
    for(i=0;i<count;i++){
        printf("       ");
        printf("%c",g.vexs[temp[i]].name);
        for(j=0;j<count;j++)
            printf("%d  ",g.arcs[temp[i]][temp[j]].adj);
        printf("\n");
    }
    printf("顶点的值为:\n");
    for(i=0;i<count;i++)
        printf("%c:%d  ",g.vexs[temp[i]].name,g.vexs[temp[i]].data);
}
    








//返回第一个邻接顶点
int FirstAdjVex(MGraph g,VertexType v)
{
    int spot,i=0;
    spot=LocateVex(g,v);
    for(i=0;i<g.vexnum;i++){
        if(g.arcs[spot][i].adj==1)
            return(i);
    }
    return(-1);//没有邻接顶点
}



int NextAdjVex(MGraph g,VertexType v,VertexType w)
{
    int spot1,spot2,i;
    spot1=LocateVex(g,v);
    spot2=LocateVex(g,w);
    for(i=spot2+1;i<g.vexnum;i++){
        if(g.arcs[spot1][i].adj==1)
            return(i);
    }
    return(-1);//没有
}

void InsertArc(MGraph &g,VertexType v,VertexType w)
{
    int spot1,spot2;
    spot1=LocateVex(g,v);
    spot2=LocateVex(g,w);
    if(spot1!=-1&&spot2!=-1)
        g.arcs[spot1][spot2].adj=1;
}


void DeleteArc(MGraph &g,VertexType v,VertexType w)
{
    int spot1,spot2;
    spot1=LocateVex(g,v);
    spot2=LocateVex(g,w);
    if(spot1!=-1&&spot2!=-1)
        g.arcs[spot1][spot2].adj=0;
}


//访问函数
void f(VertexType v)
{
    printf("%c  ",v.name);
}



//
void DFS(MGraph g,VertexType v,bool visit[])//同时可以得到连通分量
{
    int spot,stack[max_vertex_num],top=-1;
    spot=LocateVex(g,v);
    do{
        if(!visit[spot]){
            f(g.vexs[spot]);
            visit[spot]=true;
            top++;
            stack[top]=spot;
        }
        for(spot=FirstAdjVex(g,v);spot>=0;spot=NextAdjVex(g,v,g.vexs[spot])){
            if(!visit[spot])
                break;
        }
        if(spot>=0){
            v=g.vexs[spot];
            continue;
        }
        else{
            top--;
            if(top!=-1)
                spot=stack[top];
        }
    }while(top!=-1);
}






//深度优先搜索
void DFSTraverse(MGraph g)
{
    bool visit[max_vertex_num];
    int i;
    for(i=0;i<max_vertex_num;i++)
        visit[i]=false;
    for(i=0;i<g.vexnum;i++){
        if(!visit[i]) DFS(g,g.vexs[i],visit);
    }
}



//可一得到连通分量
void BFS(MGraph g,VertexType v,bool visit[])
{
      int spot,front=-1,rear=-1,queue[max_vertex_num];
      spot=LocateVex(g,v);
      f(v);
      visit[spot]=true;
      do{
          for(spot=FirstAdjVex(g,v);spot>=0;spot=NextAdjVex(g,v,g.vexs[spot])){
              if(!visit[spot]){
                  f(g.vexs[spot]);
                  visit[spot]=true;
                  rear=(rear+1)%max_vertex_num;
                  queue[rear]=spot;
              }
          }
          front=(front+1)%max_vertex_num;
          spot=queue[front];
      }while(rear==front);
}


//广度优先搜索
void BFSTraverse(MGraph g)
{
    int i;
    bool visit[max_vertex_num];
    for(i=0;i<max_vertex_num;i++)
        visit[i]=false;
    for(i=0;i<g.vexnum;i++){
        if(!visit[i]) BFS(g,g.vexs[i],visit);
    }
}


void main()
{
    MGraph T;
    int i;
    CreateGraph(T);
    printf("\n**对顶点赋值**\n");
    for(i=0;i<T.vexnum;i++)
        PutVex(T,T.vexs[i],i);
    print(T);
    printf("\n**深度优先搜索**\n");
    DFSTraverse(T);
    printf("\n广度优先搜索**\n");
    BFSTraverse(T);
}









        
        







    




    

5 楼

以上是用数组表示图的抽象数据类型,以通过运行

6 楼

用邻接多重表做的那个呢??

7 楼

还在写中

8 楼

//访问函数
void f(VertexType v)
{
    printf("%c  ",v.name);
}



//
void DFS(MGraph g,VertexType v,bool visit[])//同时可以得到连通分量
{
    int spot,stack[max_vertex_num],top=-1;
    spot=LocateVex(g,v);
    do{
        if(!visit[spot]){
            f(g.vexs[spot]);
            visit[spot]=true;
            top++;
            stack[top]=spot;
        }
        for(spot=FirstAdjVex(g,v);spot>=0;spot=NextAdjVex(g,v,g.vexs[spot])){
            if(!visit[spot])
                break;
        }
        if(spot>=0){
            v=g.vexs[spot];
            continue;
        }
        else{
            top--;
            if(top!=-1)
                spot=stack[top];
        }
    }while(top!=-1);
}






//深度优先搜索
void DFSTraverse(MGraph g)
{
    bool visit[max_vertex_num];
    int i;
    for(i=0;i<max_vertex_num;i++)
        visit[i]=false;
    for(i=0;i<g.vexnum;i++){
        if(!visit[i]) DFS(g,g.vexs[i],visit);
    }
}



//可一得到连通分量
void BFS(MGraph g,VertexType v,bool visit[])
{
      int spot,front=-1,rear=-1,queue[max_vertex_num];
      spot=LocateVex(g,v);
      f(v);
      visit[spot]=true;
      do{
          for(spot=FirstAdjVex(g,v);spot>=0;spot=NextAdjVex(g,v,g.vexs[spot])){
              if(!visit[spot]){
                  f(g.vexs[spot]);
                  visit[spot]=true;
                  rear=(rear+1)%max_vertex_num;
                  queue[rear]=spot;
              }
          }
          front=(front+1)%max_vertex_num;
          spot=queue[front];
      }while(rear==front);
}


//广度优先搜索
void BFSTraverse(MGraph g)
{
    int i;
    bool visit[max_vertex_num];
    for(i=0;i<max_vertex_num;i++)
        visit[i]=false;
    for(i=0;i<g.vexnum;i++){
        if(!visit[i]) BFS(g,g.vexs[i],visit);
    }
}

用到ADT,只要把FirstAdjVex,NextAdjVex,按邻接多重表写就行了

9 楼

#include "stdio.h"
#include "stdlib.h"
#include "iostream.h"
#define max_vertex_num 20
typedef int InfoType;
typedef char VertexType;
typedef enum{DG,DN,UDG,UDN} GraphKind;
struct ArcNode{
    int adjvex;//弧头的位置
    InfoType *info;//弧的权
    ArcNode *nextarc;
};

typedef struct VexNode{
    VertexType data;//顶点信息
    ArcNode *firstarc;//指向第一条以该顶点为弧尾的弧的指针
}VexNode,Adjlist[max_vertex_num];

typedef struct{
    Adjlist vertices;//顶点集合
    int vexnum,arcnum;
    int kind;
}ALGraph;


//对有权有向图进行操作(完全按照c语言编程)
void CreateGraph(ALGraph *g)
{
    int i,j,spot1,spot2,w;
    VertexType m,n;
    ArcNode *arc,*temp;
    printf("顶点数和弧数:");
    scanf("%d,%d",&(g->vexnum),&(g->arcnum));
    printf("顶点为:");
    for(i=0;i<g->vexnum;i++){
        cin>>g->vertices[i].data;
        g->vertices[i].firstarc=NULL;//初始化
    }
    for(;i<max_vertex_num;i++){
        g->vertices[i].data=NULL;
        g->vertices[i].firstarc=NULL;
    }
    printf("弧:");
    for(i=0;i<g->arcnum;i++){
        cin>>m;//弧尾
        cin>>n;//弧头
        cin>>w;//弧权
        for(j=0;j<g->vexnum;j++){
            if(g->vertices[j].data==m){
                spot1=j;
                break;
            }
        }
        for(j=0;j<g->vexnum;j++){
            if(g->vertices[j].data==n){
                spot2=j;
                break;
            }
        }
        arc=(ArcNode *)malloc(sizeof(ArcNode));
        arc->adjvex=spot2;
        arc->info=(int *)malloc(sizeof(int));
        *(arc->info)=w;
        arc->nextarc=NULL;
        if(g->vertices[spot1].firstarc==NULL){//建立没有头结点的链表要小心NULL
            g->vertices[spot1].firstarc=arc;
            continue;
        }
        temp=g->vertices[spot1].firstarc;
        while(temp->nextarc!=NULL)
            temp=temp->nextarc;
        temp->nextarc=arc;
        }
}

10 楼

//返回顶点的位置
int LocateVex(ALGraph g,VexNode v)
{
    int i;
    for(i=0;i<max_vertex_num;i++){
        if(g.vertices[i].data==v.data)
            return(i);
    }
    return(-1);//没有
}


//
int FirstAdjVex(ALGraph g,VexNode v)
{
    int spot;
    spot=LocateVex(g,v);
    if(g.vertices[spot].firstarc!=NULL)
        return(g.vertices[spot].firstarc->adjvex);
    return(-1);//没有
}


//
int NextAdjVex(ALGraph g,VexNode v,VexNode w)
{
    int spot;
    ArcNode *arc;
    spot=LocateVex(g,v);
    arc=g.vertices[spot].firstarc;
    while(arc!=NULL&&arc->adjvex!=LocateVex(g,w))
        arc=arc->nextarc;
    if(arc!=NULL&&arc->nextarc!=NULL)
        return(arc->nextarc->adjvex);
    return(-1);//没有
}


void DeleteVex(ALGraph *g,VexNode v)
{
    int spot,i;
    ArcNode *arc,*temp;
    spot=LocateVex(*g,v);
    g->vertices[spot].data=NULL;
    g->vertices[spot].firstarc=NULL;
    for(i=0;i<max_vertex_num;i++){
        arc=g->vertices[i].firstarc;
        if(arc==NULL) continue;
        if(arc->adjvex==spot)
            arc=NULL;
        else{
            temp=arc->nextarc;
            while(temp!=NULL&&temp->adjvex==spot){
                temp=temp->nextarc;
                arc=arc->nextarc;
            }
            if(temp!=NULL){
                arc->nextarc=temp->nextarc;
                free(temp);
                continue;
            }
        }
    }
}



//
void InsertArc(ALGraph *g,VexNode v,VexNode w)
{
    int spot1,spot2;
    ArcNode *arc,*temp;
    spot1=LocateVex(*g,v);
    spot2=LocateVex(*g,w);
    if(spot1!=-1&&spot2!=-1){
        arc=g->vertices[spot1].firstarc;
        if(arc->adjvex==spot2)
            arc=NULL;
        else{
            temp=arc->nextarc;
            while(temp->adjvex==spot2){
                arc=arc->nextarc;
                temp=temp->nextarc;
            }
            arc->nextarc=temp->nextarc;
            free(temp);
        }
    }
}



//
void DeleteArc(ALGraph *g,VexNode v,VexNode w,int value)
{
    int spot1,spot2;
    ArcNode *arc,*temp;
    spot1=LocateVex(*g,v);
    spot2=LocateVex(*g,w);
    if(spot1!=-1&&spot2!=-1){
        arc=g->vertices[spot1].firstarc;
        while(arc==NULL)
            arc=arc->nextarc;
        temp=(ArcNode *)malloc(sizeof(ArcNode));
        temp->adjvex=spot2;
        temp->nextarc=NULL;
        temp->info=(int *)malloc(sizeof(int));
        *(temp->info)=value;
        arc=temp;
    }
}


//print函数
void print(ALGraph g)
{
    int i;
    ArcNode *arc;
    for(i=0;i<max_vertex_num;i++){
        if(g.vertices[i].data!=NULL){
            printf("顶点为:%c  ",g.vertices[i].data);
            printf("邻接点为:");
            arc=g.vertices[i].firstarc;
            while(arc!=NULL){
                printf("%c  ",g.vertices[arc->adjvex].data);
                arc=arc->nextarc;
            }
        printf("\n");
        }
    }
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册