【課程設計】圖的建立和遍歷(基於鄰接表和鄰接矩陣存儲)

本課程設計主要完成鄰接矩陣和鄰接表兩種不同存儲方式的圖的建立和遍歷,其中遍歷部分分別進行了DFS和BFS兩種不同形式的遍歷。

#include<stdio.h>
#include<stdlib.h>
#include<string.h> 
#include<stack>
#include<queue>
using namespace std;

/********************************圖的存儲結構定義***********************/
#define MaxVerNum 30           
#define Vextype char
#define EdgeInfoType int

#define INF 999      //無窮大 
#define MAXSIZE 100

typedef  struct
{
    Vextype  vexs[MaxVerNum];
    EdgeInfoType edges[MaxVerNum][MaxVerNum];
    int n, e;
}MGragh;

typedef  struct node
{
    int adjvex;
    EdgeInfoType  Info;
    struct node * next;
}EdgeNode;

typedef struct vnode
{
    Vextype  vertex;
    EdgeNode *firstedge;
}VertexNode;

typedef  struct
{
    VertexNode  adjlist[MaxVerNum];
    int   n, e;
}ALGraph;

int visited[MaxVerNum];   //頂點訪問標記 

/*建立圖G的鄰接矩陣  */
int returnId(MGragh *g, char c){
//返回c在數組中的下標
    for (int i = 0; i<MaxVerNum; ++i)
    {
        if (g->vexs[i] == c) return i;
    }
    return -1;
}
void CreateGraph(MGragh *g)
{
    scanf("%d %d\n", &(g->n), &(g->e));

    char c;
    int i = 0;
    while (1)
    {
        while ((c = getchar()) == ' ');
        if (c == '\n') break;
        g->vexs[i++] = c;
    }
    Vextype s, e;
    EdgeInfoType cost;

    for (i = 0; i<g->n; i++)
    {
        for (int j = 0; j<g->n; j++)
        {
            g->edges[i][j] = 0;
        }
    }

    for (int i = 0; i<g->e; ++i)
    {
        scanf("%c %c %d\n", &s, &e, &cost);
        g->edges[returnId(g, s)][returnId(g, e)] = cost;
    }

}

/* 根據圖的鄰接矩陣建立圖的鄰接表 */
void CreateALGraph(MGragh *mg, ALGraph *alg)
{
    alg->n = mg->n; alg->e = mg->e;
    for (int i = 0; i<alg->n; ++i)
    {
        alg->adjlist[i].vertex = mg->vexs[i];
    }
    int i, j;
    EdgeNode *s;
    for (int i = 0; i < alg->n; ++i)
    {
        for (int j = 0; j < alg->n; ++j)
        {
            if (mg->edges[i][j] != 0)
            {
                s = (EdgeNode*)malloc(sizeof(EdgeNode));
                s->adjvex = j;
                s->Info = mg->edges[i][j];
                s->next = NULL;
                EdgeNode*p = alg->adjlist[i].firstedge;
                s->next = p;
                alg->adjlist[i].firstedge = s;
            }
        }
    }
}

//打印圖(鄰接矩陣) 
void printGragh(MGragh *g)
{
    printf("\n圖G的鄰接矩陣\n");
    printf("頂點:\n");
    for (int i = 0; i<g->n; i++)
    {
        printf("%c\t", g->vexs[i]);
    }
    printf("\n鄰接矩陣:\n");
    for (int i = 0; i<g->n; i++)
    {
        for (int j = 0; j<g->n; j++)
        {
            printf("%d\t", g->edges[i][j]);
        }
        printf("\n");
    }
}

//打印圖(鄰接表) 
void printALGragh(ALGraph *g)
{
    printf("\n圖G的鄰接表\n");

    for (int i = 0; i<g->n; i++)
    {
        printf("%c:", g->adjlist[i].vertex);

        EdgeNode* edge = g->adjlist[i].firstedge;
        while (edge)
        {
            printf("-->");
            printf("%d:%d\t", edge->adjvex, edge->Info);
            edge = edge->next;
        }
        printf("%\n");
    }

}



/**********************DFS*********************/
//從頂點v開始圖(鄰接矩陣)的深度遍歷 
void DFS_MG(MGragh *g, int v)
{
    int j;
    visited[v] = 1;
    printf("%c ", g->vexs[v]);

    for (j = 0; j<g->n; ++j)
    {
        if (g->edges[v][j] != 0  &&  !visited[j])
            DFS_MG(g, j);
    }

}

//圖的(鄰接矩陣)的深度遍歷 
void DFSTranverse_MG(MGragh *g)
{
    int i;
    for (i = 0; i<g->n; ++i){
        visited[i] = 0;  //初始化訪問數組visited的元素值爲false
    }
    for (i = 0; i<g->n; ++i){
        if (!visited[i]){ //節點尚未訪問
            DFS_MG(g, i);
        }
    }
}

//從頂點v開始圖(鄰接表)的深度遍歷
void DFS_ALG(ALGraph *g, int v)
{
    visited[v] = 1;
    printf("%c ", g->adjlist[v].vertex);

    EdgeNode *p =g->adjlist[v].firstedge;
    while (p){
        if (!visited[p->adjvex]){
            DFS_ALG(g, p->adjvex); //遞歸深度遍歷
        }
        p = p->next;
    }

}

//圖(鄰接表)的深度遍歷
void DFSTranverse_ALG(ALGraph *g)
{
    int i;
    for (i = 0; i<g->n; ++i){
        visited[i] = 0;  //初始化訪問數組visited的元素值爲false
    }
    for (i = 0; i<g->n; ++i){
        if (!visited[i]){ //節點尚未訪問
            DFS_ALG(g, i);
        }
    }
}

/**************************BFS****************************/

//從頂點v開始圖(鄰接矩陣)的廣度遍歷 
void BFS_MG(MGragh *g, int v)
{

    int j;
    queue<int> Q;
    visited[v] = 1;
    printf("%c ", g->vexs[v]);

    Q.push(v);

    while (!Q.empty())
    {
            
        v = Q.front();
        Q.pop();

        for (j = 0; j<g->n; ++j)
        {
            if (!visited[j] && g->edges[v][j] !=0)// INFINITY)
            {
                visited[j] = 1;
                printf("%c ", g->vexs[j]);
                Q.push(j);
            }
        }
    }
}

//圖(鄰接矩陣)的廣度遍歷
void BFSTranverse_MG(MGragh *g)
{
    int i;
    for (i = 0; i<g->n; ++i){
        visited[i] = 0;  //初始化訪問數組visited的元素值爲false
    }
    for (i = 0; i<g->n; ++i){
        if (!visited[i]){ //節點尚未訪問
            BFS_MG(g, i);
        }
    }
}

//從頂點v開始圖(鄰接表)的廣度遍歷 
void BFS_ALG(ALGraph *g, int v)
{
    queue<int > Q;
    visited[v] = 1;
    printf("%c ", g->adjlist[v].vertex);
            
    Q.push(v);
    while (!Q.empty()){     
        v = Q.front();
        Q.pop();
        EdgeNode *p = g->adjlist[v].firstedge;
        while (p){
            if (!visited[p->adjvex]){
            visited[p->adjvex] = 1;
            printf("%c ", g->adjlist[p->adjvex].vertex);            
            Q.push(p->adjvex);
            }
            p = p->next;
        }
    }

}

//圖(鄰接表)的廣度遍歷 
void BFSTranverse_ALG(ALGraph *g)
{
    int i;
    for (i = 0; i<g->n; ++i){
        visited[i] = 0;  //初始化訪問數組visited的元素值爲false
    }
    for (i = 0; i<g->n; ++i){
        if (!visited[i]){ //節點尚未訪問
            BFS_ALG(g, i);
        }
    }
}

/************************初始化與銷燬********************************/
MGragh *init_MGraph()
{
    MGragh *mg = (MGragh *)malloc(sizeof(MGragh));
    if (mg)
    {
        mg->n = 0;
        mg->e = 0;
    }

    return mg;
}

ALGraph *init_ALGraph()
{
    ALGraph *alg = (ALGraph *)malloc(sizeof(ALGraph));
    if (alg)
    {
        alg->n = 0;
        alg->e = 0;
        for (int i = 0; i<MaxVerNum; i++)
            alg->adjlist[i].firstedge = NULL;
    }

    return alg;
}

void destroy_MGraph(MGragh **g)
{
    if (*g)
    {
        free(*g);
        *g = NULL;
    }
}

void destroy_ALGraph(ALGraph **g)
{
    for (int i = 0; i < (*g)->n; ++i)
    {
        EdgeNode *p = (*g)->adjlist[i].firstedge;
        while (p)
        {
            EdgeNode *q = p->next;
            free(p);
            p = q;
        }
    }

    if (*g)
    {
        free(*g);
        *g = NULL;
    }
}

/****main函數*************/
int main()
{
    freopen("數據.txt", "r", stdin);
    //創建圖(鄰接矩陣) 
    MGragh *mG = init_MGraph();
    CreateGraph(mG);
    printGragh(mG);

    //創建圖(鄰接表) 
    ALGraph *alG = init_ALGraph();
    CreateALGraph(mG, alG);
    printALGragh(alG);

    
    //DFS遍歷
    printf("\nDFS遍歷:\n");
    printf("鄰接矩陣:\n");
    DFSTranverse_MG(mG);
    printf("\n鄰接表:\n");
    DFSTranverse_ALG(alG);

    //BFS遍歷
    printf("\n\nBFS遍歷:\n");
    printf("鄰接矩陣:\n");
    BFSTranverse_MG(mG);
    printf("\n鄰接表:\n");
    BFSTranverse_ALG(alG);

    //銷燬圖
    destroy_MGraph(&mG);
    destroy_ALGraph(&alG);
    
}
//運行成功 2019年5月14日0:19:36

程序利用freopen("數據.txt", "r", stdin)將標準輸入定位到“數據.txt”中,從該文件讀取數據,文件格式如下:

圖數據格式

 

運行結果如下:

運行結果

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章