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;

}

 

收藏 打印