邻接表存储的图计算连通分量
按照王道书的函数名称做滴
#include<stdio.h>
#include<string.h>
#include <iostream>
#include<algorithm>
using namespace std;
#define MVNum 2
#define INF 0x3f3f3f3f
int vis[MVNum];
typedef struct ArcNode /* 边表结点 */
{
int adjvex; /* 邻接点域,存储该顶点对应的下标 */
int info; /* 用于存储权值,对于非网图可以不需要 */
struct ArcNode* nextarc; /* 链域,指向下一个邻接点 */
}ArcNode;
typedef struct VNode /* 顶点表结点 */
{
char data; /* 顶点域,存储顶点信息 */
ArcNode* firstarc; /* 边表头指针 */
}VNode, AdjList[MVNum];//头结点数组
typedef struct
{
AdjList vertices;
int vexnum, arcnum; /* 图中当前顶点数和边数 */
}ALGraph;
int LocateVex(ALGraph& G, char v)//找到v在邻接表G中的位置
{
for (int i = 0; i < G.vexnum; i++)
{
if (G.vertices[i].data == v)
return i;
}
return -1;
}
void ListGraphInit(ALGraph& L, int map[MVNum][MVNum]) {
memset(&L, 0, sizeof(L));
for (int i = 0; i < MVNum; i++) {
L.vexnum++;
int mark = 0;
for (int j = 0; j < MVNum; j++) {
if(mark==0 && j==MVNum-1 && map[i][j]==INF) { //如果一个点没有任何边 则创建新的无边头结点
L.vertices[i].firstarc = (ArcNode*)malloc(sizeof(ArcNode));
L.vertices[i].firstarc->adjvex = -1;
L.vertices[i].firstarc->info = 0;
L.vertices[i].firstarc->nextarc = nullptr;
}
if (map[i][j] != INF && (i != j)) {
L.arcnum++;
if (!mark) { //建立头结点
mark++;
L.vertices[i].firstarc = (ArcNode*)malloc(sizeof(ArcNode));
L.vertices[i].firstarc->adjvex = j;
L.vertices[i].firstarc->info = 0;
L.vertices[i].firstarc->nextarc = nullptr;
}
else
{
//建立该顶点与其他顶点的边
ArcNode* p = L.vertices[i].firstarc, * q;
while (p->nextarc != nullptr)
p = p->nextarc;
q = (ArcNode*)malloc(sizeof(ArcNode));
p->nextarc = q;
q->info = map[i][j];
q->adjvex = j;
q->nextarc = nullptr;
}
}
}
}
}
int NextNeighbor(ALGraph G, int x, int y)
{
//以邻接表作为存储结构
if (x != -1)
{
ArcNode* p = G.vertices[x].firstarc;
while (p != NULL && p->adjvex != y)
{
p = p->nextarc;
}
if (p != NULL && p->nextarc != NULL)
return p->nextarc->adjvex; //返回除了y以外x的下一个邻接点 若y是x最后一个邻接点 返回-1
}
return -1;
}
int FirstNeighbor(ALGraph G, int x) {//求G的顶点x的第一个邻接点 有就返回顶点号 没有邻接点就返回-1
ArcNode* p = G.vertices[x].firstarc;
if (p->adjvex) return p->adjvex;
return -1;
}
void DFS(ALGraph G, int v)
{
int w;
vis[v] = 1; //结点标记
for(w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w))
{
if (!vis[w])
DFS(G, w);
}
}
void ListGraphOutput(ALGraph& L) {
printf("邻接表信息如下: \n");
printf("\t该邻接表共有%d个结点与%d条边\n",L.vexnum,L.arcnum );
printf("\t结点信息如下: \n");
printf("\t弧的具体信息如下: \n");
for (int i = 0; i < L.vexnum; i++) {
printf("\t\t%d->", i);
if (L.vertices[i].firstarc->adjvex<0) return;
printf("%d", L.vertices[i].firstarc->adjvex);
ArcNode* p = L.vertices[i].firstarc->nextarc;
while (p) {
printf("->%d", p->adjvex);
p = p->nextarc;
}
putchar(10);
}
putchar(10);
}
int main(void)
{
ALGraph G;
int m = INF;
int map[MVNum][MVNum] = {
0, 5,
2, 0,
};
ListGraphInit(G, map);
ListGraphOutput(G);
int num = 0;
memset(vis, 0, sizeof(vis)); //大小裁剪
for (int v = 0; v < G.vexnum; v++) // 读入顶点信息,建立顶点表
{
if (!vis[v])
{
DFS(G, v);
num++;
}
}
printf("\n连通分量个数:%d\n", num);
return 0;
}