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;
}