图的储存与遍历代码实现

1. 分别用邻接矩阵和邻接表储存图

2. 实现邻接矩阵和邻接表的相互转化

3. 分别用深度优先搜索和广度优先搜索遍历图

 

下方代码所依据的图:

代码:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
 
//图的两种存储结构
#define INFINITY 32767          // 值∞
#define MAX_VERTEX_NUM 8        // 最大顶点个数
typedef char InfoType;          // 其他信息
 
typedef struct {
    int no;                                 //顶点编号
    InfoType *info;                         //顶点其他信息
} VertexType;                               //顶点类型
 
// 图的数组(邻接矩阵)存储表示
typedef struct {
    VertexType vexs[MAX_VERTEX_NUM];                // 顶点向量
    int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];       // 邻接矩阵数组
    int n, e;              // 图的当前顶点数和弧数
} MGraph;
 
// 图的邻接表存储表示
typedef struct ArcNode {    // 链表结点
    int adjvex;             // 该弧所指向的顶点的位置
    int weight;             // 网的权值指针
    ArcNode *nextarc;       // 指向下一条弧的指针
} ArcNode;
 
typedef struct {
    VertexType data;        // 顶点信息
    ArcNode *firstarc;      // 第一个表结点的地址,指向第一条依附该顶点的弧的指针
} VNode;
 
typedef struct  {
    VNode adjlist[MAX_VERTEX_NUM];      //adjacency List 邻接表
    int n, e; // 图的当前顶点数和弧数
} ALGraph;
 
//创建图的邻接表
void CreateAdj(ALGraph *G, int A[][MAX_VERTEX_NUM], int n, int e)
{
    ArcNode *p;
    G->n = n;
    G->e = e;
    // 初始化顶点信息
    for(int i=0;i<G->n;i++) {
        G->adjlist[i].data.no = i;       // i+1
        G->adjlist[i].firstarc = NULL;
    }
    for(int i=0;i<MAX_VERTEX_NUM;i++) {
        for(int j=0;j<MAX_VERTEX_NUM;j++) {
            if(A[i][j] == 1) {
                p = (ArcNode*)malloc(sizeof(ArcNode));
                p->adjvex = j;
                p->weight = 0;  // 不带权
                p->nextarc = G->adjlist[i].firstarc;    //头插法
                G->adjlist[i].firstarc = p;
            }
        }
    }
}
//创建图的邻接矩阵
void CreateMat(MGraph &g, int A[][MAX_VERTEX_NUM], int n, int e)
{
    for(int i=0;i<MAX_VERTEX_NUM;i++)
        for(int j=0;j<MAX_VERTEX_NUM;j++)
            g.arcs[i][j] = A[i][j];
    g.n = n;
    g.e = e;
}
//输出邻接矩阵
void DispMatrix(MGraph g)
{
    cout << "邻接矩阵:\n";
    for(int i=0;i<MAX_VERTEX_NUM;i++) {
        for(int j=0;j<MAX_VERTEX_NUM;j++)
            cout << g.arcs[i][j] << " ";
        cout << endl;
    }
}
void Show(ArcNode *temp,ArcNode *head)  //前面采用头插法,所以此处用递归倒序输出
{
    if(temp == NULL)
        return;
 
    Show(temp->nextarc,head);
    cout << temp->adjvex;
    if(temp != head)
        cout << "->";
}
//输出邻接表
void DispAdjList(ALGraph *G)
{
    cout << "邻接表:\n";
    for(int k=0;k<G->n;k++) {
        printf("%d: ",G->adjlist[k].data.no);
        Show(G->adjlist[k].firstarc,G->adjlist[k].firstarc);
        cout << endl;
    }
}
//将邻接矩阵 g 转换成邻接表 G
void MatrixToList(MGraph g, ALGraph &G)
{
    CreateAdj(&G,g.arcs,g.n,g.e);
    // 没错就这这么easy
}
//将邻接表 G 转换成邻接矩阵 g
void ListToMatrix(ALGraph G, MGraph &g)
{
    g.n = G.n;
    g.e = G.e;
    for(int i=0;i<g.n;i++)
        for(int j=0;j<g.n;j++)
            g.arcs[i][j] = 0;       //初始化邻接矩阵
    for(int i=0;i<G.n;i++) {
        ArcNode *p = G.adjlist[i].firstarc;
        while(p != NULL) {
            int k = p->adjvex;
            g.arcs[i][k] = 1;
            p = p->nextarc;
        }
    }
}
// 图的深度优先搜
 
bool book[MAX_VERTEX_NUM];
int Count;
void DFS(ALGraph tree,int x,int a[])
{
    if( !book[x]) {
        a[Count++] = tree.adjlist[x].data.no+1;
        book[x] = true;
        ArcNode *temp3 = tree.adjlist[x].firstarc;
        while(temp3 != NULL) {
            DFS(tree,temp3->adjvex,a);
            temp3 = temp3->nextarc;
        }
    }
}
void DFS_Branchs(ALGraph tree,int start,int a[])   //将遍历结果保存到数组a中,
{
    // 从第start个点开始遍历,下标为start-1
 
    for(int i=0;i<MAX_VERTEX_NUM;i++)
        book[i] = false;  //标记是否访问过
    int now = start-1;
    Count = 0;
    for(int k=0;k<MAX_VERTEX_NUM;k++) {  //n个结点最多n个分支
        if( !book[now]) {
            a[Count++] = tree.adjlist[now].data.no+1;   //编号为i的点是第i+1个点 (下标从0开始)
            book[now] = true;
            ArcNode *temp3 = tree.adjlist[now].firstarc;
            while(temp3!=NULL) {
                DFS(tree,temp3->adjvex,a);
                temp3 = temp3->nextarc;
            }
        }
        now = (now+1)%MAX_VERTEX_NUM;
    }
}
void BFS(ALGraph tree,int start,int a[])
{
    for(int i=0;i<MAX_VERTEX_NUM;i++)
        book[i] = false;
    int head=0,tail=0;
    int now = start-1;
    for(int k=0;k<MAX_VERTEX_NUM;k++) { //最多MAX_VERTEX_NUM个分支
        if( !book[now]) {
            a[tail++] = tree.adjlist[now].data.no+1;
            book[now] = true;
        }
        while(head < tail) {
            now = a[head]-1;
            ArcNode *p = tree.adjlist[now].firstarc;
            while(p!=NULL) {
                if(!book[p->adjvex]) {
                    a[tail++] = p->adjvex + 1;
                    book[p->adjvex] = true;
                }
                p = p->nextarc;
            }
            head++;
        }
        now = (now+1)%MAX_VERTEX_NUM;
    }
 
}
int main()
{
    int map1[MAX_VERTEX_NUM][MAX_VERTEX_NUM] = {{0,1,1,0,0,0,0,0},
                                                {1,0,0,1,1,0,0,0},
                                                {1,0,0,0,0,1,1,0},
                                                {0,1,0,0,0,0,0,1},
                                                {0,1,0,0,0,0,0,1},
                                                {0,0,1,0,0,0,1,0},
                                                {0,0,1,0,0,1,0,0},
                                                {0,0,0,1,1,0,0,0}};
    MGraph Graph1;
    CreateMat(Graph1,map1,8,9);
    DispMatrix(Graph1);
 
    ALGraph Graph2;
    CreateAdj(&Graph2,map1,8,9);
    DispAdjList(&Graph2);
 
    ALGraph Graph3;
    MatrixToList(Graph1,Graph3); //将邻接矩阵Graph1转为邻接表Graph3
    cout << "邻接矩阵转邻接表:\n";
    DispAdjList(&Graph3);
 
    MGraph Graph4;
    ListToMatrix(Graph2,Graph4); //将邻接表Graph2转为邻接矩阵Graph4
    cout << "邻接表转邻接矩阵:\n";
    DispMatrix(Graph4);
 
//  深度优先搜索 Graph2
    cout << "对Graph2进行深度优先遍历:\n";
    int me_1[MAX_VERTEX_NUM]={0};
    DFS_Branchs(Graph2,5,me_1);
    for(int i=0;i<MAX_VERTEX_NUM;i++)
        cout << me_1[i] << " ";
    cout << endl;
 
//  广度优先搜索Graph2
    cout << "对Graph2进行广度优先遍历:\n";
    int me_2[MAX_VERTEX_NUM] = {0};
    BFS(Graph2,3,me_2);
    for(int i=0;i<MAX_VERTEX_NUM;i++)
        cout << me_2[i] << " ";
    cout << endl;
 
}

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值