课程设计——图的建立和遍历(基于邻接表和邻接矩阵存储)

本课程设计主要完成邻接矩阵和邻接表两种不同存储方式的图的建立和遍历,其中遍历部分分别进行了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”中,从该文件读取数据,文件格式如下:


图数据格式

运行结果如下:


运行结果
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • 一、动态规划 找到两点间的最短路径,找最匹配一组点的线,等等,都可能会用动态规划来解决。 参考如何理解动态规划中,...
    小碧小琳阅读 24,731评论 2 20
  • 1 概述 图是数据结构中最复杂的形式,也是最烧脑的结构。无数的牛人乐此不疲地钻研,然而,时至今日,依然有很多问题等...
    CodingTech阅读 2,293评论 0 8
  • 图是一种灵活的数据结构,一般作为一种模型用来定义对象之间的关系或联系。对象由顶点(V)表示,而对象之间的关系或者关...
    卡巴拉的树阅读 81,410评论 27 120
  • 图是一种灵活的数据结构,一般作为一种模型用来定义对象之间的关系或联系。对象由顶点(V)表示,而对象之间的关系或者关...
    ad丶leo阅读 865评论 0 0
  • 今天在图书馆呆了将近5个小时,终于解出了认为自己智商仿佛触碰不到的盲区。 跳出固定思维 只要努力,希望还是有的
    AlisterZHOU阅读 84评论 0 0