1. 程式人生 > >圖的鄰接表表示及遍歷

圖的鄰接表表示及遍歷

圖也可以用鄰接表表示。各個結點中存放了結點的資訊,並且由一個指標變數,指向第一條邊,第一條變又指向第二條邊,以此類推。圖的鄰接表的程式碼如下:

/********************************/
/******圖的鄰接表的建立及遍歷****/
#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);
}