Bootstrap

图的邻接表表示法&图的遍历

第1关:图的邻接表表示法

#include <stdio.h>
#include <stdlib.h>

#define MVNum 100 // 最大顶点数

typedef char VerTexType; // 顶点信息
typedef int OtherInfo;   // 和边相关的信息

// - - - - -图的邻接表存储表示- - - - -
typedef struct ArcNode {         // 边结点
    int adjvex; // 该边所指向的顶点的位置
    struct ArcNode* nextarc;     // 指向下一条边的指针
    OtherInfo info; // 和边相关的信息
} ArcNode;

typedef struct VNode {
    VerTexType data; // 顶点信息
    ArcNode* firstarc;           // 指向第一条依附该顶点的边的指针
} VNode, AdjList[MVNum];         // AdjList表示邻接表类型

typedef struct {
    AdjList vertices; // 邻接表
    int vexnum, arcnum;          // 图的当前顶点数和边数
} ALGraph;

// 确定点v在G中的位置
int LocateVex(ALGraph G, VerTexType v) {
    for (int i = 0; i < G.vexnum; i++) {
        if (G.vertices[i].data == v) {
            return i;
        }
    }
    return -1;
}

// 创建无向图函数CreateUDG
void CreateUDG(ALGraph* G) {
    int i, j, k;
    VerTexType v1, v2;

    //printf("请输入总顶点数,总边数:\n");
    scanf("%d %d\n", &G->vexnum, &G->arcnum);

    //printf("输入顶点的信息:\n");
    for (i = 0; i < G->vexnum; i++) {
        scanf("%c\n", &G->vertices[i].data);
        G->vertices[i].firstarc = NULL; // 初始化边链表
    }

    //printf("输入每条边依附的两个顶点:\n");
    for (k = 0; k < G->arcnum; k++) {
        scanf("%c %c\n", &v1, &v2);
        i = LocateVex(*G, v1);
        j = LocateVex(*G, v2);

        // 为v1创建边结点
        ArcNode* p1 = (ArcNode*)malloc(sizeof(ArcNode));
        p1->adjvex = j;
        p1->nextarc = G->vertices[i].firstarc;
        G->vertices[i].firstarc = p1;

        // 为v2创建边结点 (因为是无向图,双向添加)
        ArcNode* p2 = (ArcNode*)malloc(sizeof(ArcNode));
        p2->adjvex = i;
        p2->nextarc = G->vertices[j].firstarc;
        G->vertices[j].firstarc = p2;
    }
}

int main() {
    ALGraph G;
    int i;
    CreateUDG(&G);

    printf("*****邻接表表示法创建的无向网*****\n");

    for (i = 0; i < G.vexnum; ++i) {
        VNode temp = G.vertices[i];
        ArcNode* p = temp.firstarc;
        if (p == NULL) {
            printf("%c\n", G.vertices[i].data);
        }
        else {
            printf("%c", temp.data);
            while (p) {
                printf("->%d", p->adjvex);
                p = p->nextarc;
            }
        }
        printf("\n");
    }

    return 0;
}

第2关:采用邻接表表示图的深度优先搜索遍历

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MVNum 100 

typedef char VerTexType; 
typedef int OtherInfo;   

typedef struct ArcNode {         
    int adjvex; 
    struct ArcNode* nextarc;   
    OtherInfo info;
} ArcNode;

typedef struct VNode {
    VerTexType data; 
    ArcNode* firstarc;         
} VNode, AdjList[MVNum];        

typedef struct {
    AdjList vertices; 
    int vexnum, arcnum;         
} ALGraph;

bool visited[MVNum];

int LocateVex(ALGraph G, VerTexType v) {
    for (int i = 0; i < G.vexnum; i++) {
        if (G.vertices[i].data == v) {
            return i;
        }
    }
    return -1;
}

void CreateUDG(ALGraph* G) {
    int i, j, k;
    VerTexType v1, v2;

    scanf("%d %d\n", &G->vexnum, &G->arcnum);

    for (i = 0; i < G->vexnum; i++) {
        scanf("%c\n", &G->vertices[i].data);
        G->vertices[i].firstarc = NULL; 
    }

    for (k = 0; k < G->arcnum; k++) {
        scanf("%c %c\n", &v1, &v2);
        i = LocateVex(*G, v1);
        j = LocateVex(*G, v2);

        ArcNode* p1 = (ArcNode*)malloc(sizeof(ArcNode));
        p1->adjvex = j;
        p1->nextarc = G->vertices[i].firstarc;
        G->vertices[i].firstarc = p1;

        ArcNode* p2 = (ArcNode*)malloc(sizeof(ArcNode));
        p2->adjvex = i;
        p2->nextarc = G->vertices[j].firstarc;
        G->vertices[j].firstarc = p2;
    }
}

void DFS_AL(ALGraph G, int v) {
    printf("%c   ", G.vertices[v].data); 
    visited[v] = true; 
    ArcNode* p = G.vertices[v].firstarc;
    while (p) {
        if (!visited[p->adjvex]) {
            DFS_AL(G, p->adjvex); 
        }
        p = p->nextarc; 
    }
}

int main() {
    ALGraph G;
    int i;
    CreateUDG(&G); 

    VerTexType c;
    scanf("%c\n", &c);

    for (i = 0; i < G.vexnum; ++i) {
        if (c == G.vertices[i].data) {
            break;
        }
    }

    while (i >= G.vexnum) {
        printf("该点不存在,请重新输入!\n");
        scanf("%c\n", &c);
        for (i = 0; i < G.vexnum; ++i) {
            if (c == G.vertices[i].data) {
                break;
            }
        }
    }

    printf("深度优先搜索遍历图结果:\n");
    for (int j = 0; j < G.vexnum; j++) {
        visited[j] = false; 
    }
    DFS_AL(G, i); 
    printf("\n");

    return 0;
}

第3关:采用邻接表表示图的广度优先搜索遍历

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MVNum 100 // 最大顶点数
#define MAXQSIZE 100 // 最大队列长度

typedef char VerTexType; // 顶点信息
typedef int ArcType; // 假设边的权值类型为整型
typedef int OtherInfo; // 和边相关的信息

// - - - - -图的邻接表存储表示- - - - -
typedef struct ArcNode { // 边结点
    int adjvex; // 该边所指向的顶点的位置
    struct ArcNode *nextarc; // 指向下一条边的指针
    OtherInfo info; // 和边相关的信息
} ArcNode;

typedef struct VNode {
    VerTexType data; // 顶点信息
    ArcNode *firstarc; // 指向第一条依附该顶点的边的指针
} VNode, AdjList[MVNum]; // AdjList表示邻接表类型

typedef struct {
    AdjList vertices; // 邻接表
    int vexnum, arcnum; // 图的当前顶点数和边数
} ALGraph;

bool visited[MVNum]; // 访问标志数组,其初值为"false"

// ----队列的定义及操作--------
typedef struct {
    ArcType *base; // 初始化的动态分配存储空间
    int front; // 头指针,若队列不空,指向队头元素
    int rear; // 尾指针,若队列不空,指向队尾元素的下一个位置
} sqQueue;

void InitQueue(sqQueue *Q) {
    Q->base = (ArcType *)malloc(MAXQSIZE * sizeof(ArcType));
    if (!Q->base) exit(0); // 存储分配失败
    Q->front = Q->rear = 0; // 初始化为空队列
}

void EnQueue(sqQueue *Q, ArcType e) {
    if ((Q->rear + 1) % MAXQSIZE == Q->front) return; // 队列满
    Q->base[Q->rear] = e;
    Q->rear = (Q->rear + 1) % MAXQSIZE;
}

bool QueueEmpty(sqQueue Q) {
    return Q.front == Q.rear;
}

void DeQueue(sqQueue *Q, ArcType *u) {
    if (Q->front == Q->rear) return; // 队列空
    *u = Q->base[Q->front];
    Q->front = (Q->front + 1) % MAXQSIZE;
}

int LocateVex(ALGraph G, VerTexType v) {
    for (int i = 0; i < G.vexnum; i++) {
        if (G.vertices[i].data == v) {
            return i;
        }
    }
    return -1;
}

void CreateUDG(ALGraph *G) {
    int i, j, k;
    VerTexType v1, v2;

    printf("请输入总顶点数,总边数:\n");
    scanf("%d %d\n", &G->vexnum, &G->arcnum);

    printf("输入顶点的信息:\n");
    for (i = 0; i < G->vexnum; i++) {
        scanf("%c\n", &G->vertices[i].data);
        G->vertices[i].firstarc = NULL; // 初始化边链表
    }

    printf("输入每条边依附的两个顶点:\n");
    for (k = 0; k < G->arcnum; k++) {
        scanf("%c %c\n", &v1, &v2);
        i = LocateVex(*G, v1);
        j = LocateVex(*G, v2);

        // 为v1创建边结点
        ArcNode *p1 = (ArcNode *)malloc(sizeof(ArcNode));
        p1->adjvex = j;
        p1->nextarc = G->vertices[i].firstarc;
        G->vertices[i].firstarc = p1;

        // 为v2创建边结点 (因为是无向图,双向添加)
        ArcNode *p2 = (ArcNode *)malloc(sizeof(ArcNode));
        p2->adjvex = i;
        p2->nextarc = G->vertices[j].firstarc;
        G->vertices[j].firstarc = p2;
    }
}

void BFS(ALGraph G, int v) {
    sqQueue Q;
    InitQueue(&Q);
    printf("%c   ", G.vertices[v].data); // 访问该顶点
    visited[v] = true; // 标记已访问
    EnQueue(&Q, v);

    while (!QueueEmpty(Q)) {
        int u;
        DeQueue(&Q, &u); // 队头元素出队
        ArcNode *p = G.vertices[u].firstarc;
        while (p) {
            if (!visited[p->adjvex]) {
                printf("%c   ", G.vertices[p->adjvex].data); // 访问该顶点
                visited[p->adjvex] = true; // 标记已访问
                EnQueue(&Q, p->adjvex); // 入队
            }
            p = p->nextarc;
        }
    }
}

int main() {
    ALGraph G;
    int i;
    CreateUDG(&G); // 调用创建无向图函数CreateUDG

    VerTexType c;
    scanf("%c\n", &c);

    for (i = 0; i < G.vexnum; ++i) {
        if (c == G.vertices[i].data) {
            break;
        }
    }

    while (i >= G.vexnum) {
        printf("该点不存在,请重新输入!\n");
        printf("请输入遍历连通图的起始点:");
        scanf("%c\n", &c);
        for (i = 0; i < G.vexnum; ++i) {
            if (c == G.vertices[i].data) {
                break;
            }
        }
    }

    printf("广度优先搜索遍历图结果:\n");
    for (int j = 0; j < G.vexnum; j++) {
        visited[j] = false; // 确保访问标志数组在遍历前被重置
    }
    BFS(G, i); // 调用广度优先搜索遍历图函数BFS
    printf("\n");

    return 0;
}

;