图的邻接表表示及遍历

图也可以用邻接表表示。各个结点中存放了结点的信息,并且由一个指针变量,指向第一条边,第一条变又指向第二条边,以此类推。图的邻接表的代码如下:

/********************************/
/******图的邻接表的建立及遍历****/
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#define MaxVerNum 100
#define QueueSize 30
typedef enum{FALSE,TRUE} Boolean;

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

typedef struct VNode
{
    char data;//顶点信息
    ArcNode *firstarc;//指向第一条边的指针
}VNode;

typedef struct
{
    VNode adjlist[MaxVerNum];
    int n,e;
}AGraph;

/******************************************/
/**建立有向图的邻接表算法*****************/ 
Boolean visited[MaxVerNum];

    void CreateAGraph(AGraph * G)
    {
    int i,j,k;
    ArcNode * s;
    printf("请输入顶点数和边数(输入格式为:顶点数,边数):");
    scanf("%d,%d",&(G->n),&(G->e));
    printf("请输入顶点信息,每个顶点以回车作为结束:\n");
    /*建立顶点表,顶点从0开始编号*/
    
    for(i=0;i<G->n;i++)
    {
        scanf("\n%c",&(G->adjlist[i].data));

        G->adjlist[i].firstarc=NULL;
    }

    printf("请输入边的信息(i,j):\n");//回车作为结束

    for(k=0;k<G->e;k++)
    {    
        
        scanf("%d,%d",&i,&j);
        
        s=(ArcNode *)malloc(sizeof(ArcNode));
        if(s!=NULL)
        {
            s->adjvex=j;
            s->nextarc=G->adjlist[i].firstarc;
            G->adjlist[i].firstarc=s;
            s=NULL;
            /*对于无向图在申请一块内存用来存放边即可 */
            //s=(ArcNode * )malloc(sizeof(ArcNode));
              if(s!=NULL)
              {
                  s->adjvex=i;
                  s->nextarc=G->adjlist[j].firstarc;
                  G->adjlist[i].firstarc=s;
                  s=NULL;
              }
        }
        
    }
    

    }
    /****深度优先遍历******************************/

    void DFS(AGraph *G,int vi)//以vi为出发点对邻接表表示的图进行深度优先搜索
    {
        ArcNode * p=NULL;
        visited[vi]=TRUE;
        printf("visited vextex : %c\n",G->adjlist[vi].data);
        p=G->adjlist[vi].firstarc;
        while(p!=NULL)
        {
            if(visited[p->adjvex]==FALSE)
                DFS(G,p->adjvex);
                p=p->nextarc;
        }
    }

    void DFSTraver(AGraph *G)
    {
        int i;
        for(i=0;i<G->n;i++)
            visited[i]=FALSE;
        for(i=0;i<G->n;i++)
            if(!visited[i])
                DFS(G,i);
    }
/******************************************************/
/*****广度优先遍历*************************************/
typedef struct 
{
    int front ;
    int rear;
    int count;
    int data[QueueSize];

}CirQueue;

void InitQueue(CirQueue * Q)
{
    Q->front=Q->rear=0;
    Q->count=0;
};

int QueueEmpty(CirQueue *Q)
{
    return Q->count==0;
}
int QueueFull(CirQueue *Q)
{
    return Q->count==QueueSize;
}
void EnQueue(CirQueue *Q,int x)
{
    if(QueueFull(Q))
        printf("Queue overflow\n");
    else
    {
        Q->count++;
        Q->data[Q->rear]=x;
        Q->rear=(Q->rear+1)%QueueSize;
    }
}
int  DeQueue(CirQueue * Q)
{
    int temp;
    if(QueueEmpty(Q))
        printf("Queue underflow\n");
    else
    {
        temp=Q->data[Q->front];
        Q->count--;
        Q->front=(Q->front+1)%QueueSize;
        return temp;
    }
}

void BFS(AGraph *G,int k)//以k为源点进行广度优先搜索
{
    int i;
    CirQueue Q;
    ArcNode * p;
    InitQueue(&Q);
    visited[k]=TRUE;
    printf("广度优先遍历结点:%c\n",G->adjlist[k].data);
    EnQueue(&Q,k);
    while(!QueueEmpty(&Q))
    {
        i=DeQueue(&Q);
        p=G->adjlist[i].firstarc;
        while(p)
        {
            if(!visited[p->adjvex])
            {
                printf("广度优先遍历结点:%c\n",G->adjlist[p->adjvex].data);
                visited[p->adjvex]=TRUE;
                EnQueue(&Q,p->adjvex);
            }
            p=p->nextarc;
        }
    }

}

void BFSTraver(AGraph *G)
{
    int i;
    for(i=0;i<G->n;i++)
        visited[i]=FALSE;
    for(i=0;i<G->n;i++)
    {
        if(!visited[i])
            BFS(G,i);
    }
}
    
void main(void)
{
    AGraph G;
    CreateAGraph(&G);
    DFSTraver(&G);
    BFSTraver(&G);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值