第六章 图

1.无向图 邻接矩阵

#include <stdio.h>
#include <stdbool.h>
#define MaxVertexNum 100

typedef struct {
    int Vex[MaxVertexNum];         // 顶点
    int Edge[MaxVertexNum][MaxVertexNum];  // 邻接矩阵,0 表示没有边
    int vexnum, arcnum;            // 顶点数和边数
} MGraph;

void initGraph(MGraph* graph, int numVertices) {
    graph->vexnum = numVertices;
    graph->arcnum = 0;  // 初始化时没有边

    // 初始化邻接矩阵
    for (int i = 0; i < numVertices; i++) {
        for (int j = 0; j < numVertices; j++) {
            graph->Edge[i][j] = 0;  // 所有边置为0,表示没有边
        }
    }
}

void insertEdge(MGraph* graph, int start, int end) {
    if (start >= 0 && start < graph->vexnum && end >= 0 && end < graph->vexnum) {
        if (graph->Edge[start][end] == 0) {  // 避免重复添加边
            graph->Edge[start][end] = 1;  // 添加边
            graph->Edge[end][start] = 1;  // 无向图边是双向的
            graph->arcnum++;
        }
    }
}

void removeEdge(MGraph* graph, int start, int end) {
    if (start >= 0 && start < graph->vexnum && end >= 0 && end < graph->vexnum) {
        if (graph->Edge[start][end] == 1) {  // 只有存在边时才移除
            graph->Edge[start][end] = 0;
            graph->Edge[end][start] = 0;
            graph->arcnum--;
        }
    }
}

bool hasEdge(MGraph* graph, int start, int end) {
    if (start >= 0 && start < graph->vexnum && end >= 0 && end < graph->vexnum) {
        return graph->Edge[start][end] == 1;
    }
    return false;
}

int firstNeighbor(MGraph* graph, int x) {
    if (x >= 0 && x < graph->vexnum) {
        for (int i = 0; i < graph->vexnum; i++) {
            if (graph->Edge[x][i] == 1) {
                return i;
            }
        }
    }
    return -1; // 没有邻接点
}

void neighborsExceptY(MGraph* graph, int x, int y) {
    if (x >= 0 && x < graph->vexnum && y >= 0 && y < graph->vexnum) {
        for (int i = 0; i < graph->vexnum; i++) {
            if (graph->Edge[x][i] == 1 && i != y) {
                printf("%d ", i);
            }
        }
        printf("\n");
    }
}

int main() {
    MGraph graph;
    int numVertices = 5;  // 假设有5个顶点

    initGraph(&graph, numVertices);

    insertEdge(&graph, 0, 1);
    insertEdge(&graph, 0, 2);
    insertEdge(&graph, 1, 3);

    printf("Number of vertices: %d\n", graph.vexnum);
    printf("Number of edges: %d\n", graph.arcnum);

    if (hasEdge(&graph, 0, 1)) {
        printf("There is an edge between 0 and 1.\n");
    } else {
        printf("There is no edge between 0 and 1.\n");
    }
    printf("First neighbor of vertex 0: %d\n", firstNeighbor(&graph, 0));
    printf("Neighbors of vertex 0 except vertex 1: ");
    neighborsExceptY(&graph, 0, 1);
    removeEdge(&graph, 0, 1);
    return 0;
}

2.无向图 邻接表

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_VERTICES 100
// 结点结构
struct Node {
    int vertex;
    struct Node* next;
};
// 邻接表结构
struct Graph {
    struct Node* adjList[MAX_VERTICES];
};

int numVertices = 0;

// 初始化图
struct Graph* createGraph() {
    struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));
    for (int i = 0; i < MAX_VERTICES; i++) {
        graph->adjList[i] = NULL;
    }
    return graph;
}

// 插入顶点
void insertVertex(struct Graph* graph, int vertex) {
    if (numVertices < MAX_VERTICES) {
        numVertices++;
    }
}

// 删除顶点
void deleteVertex(struct Graph* graph, int vertex) {
    if (vertex < numVertices) {
        // 删除与该顶点相关的边
        for (int i = 0; i < numVertices; i++) {
            struct Node* current = graph->adjList[i];
            struct Node* prev = NULL;
            while (current != NULL) {
                if (current->vertex == vertex) {
                    if (prev == NULL) {
                        graph->adjList[i] = current->next;
                    } else {
                        prev->next = current->next;
                    }
                    free(current);
                    break;
                }
                prev = current;
                current = current->next;
            }
        }
        // 移动其他顶点的索引
        for (int i = vertex; i < numVertices - 1; i++) {
            graph->adjList[i] = graph->adjList[i + 1];
        }
        numVertices--;
    }
}

// 添加边
void addEdge(struct Graph* graph, int vertex1, int vertex2) {
    if (vertex1 < numVertices && vertex2 < numVertices) {
        struct Node* newNode1 = (struct Node*)malloc(sizeof(struct Node));
        newNode1->vertex = vertex2;
        newNode1->next = graph->adjList[vertex1];
        graph->adjList[vertex1] = newNode1;

        struct Node* newNode2 = (struct Node*)malloc(sizeof(struct Node));
        newNode2->vertex = vertex1;
        newNode2->next = graph->adjList[vertex2];
        graph->adjList[vertex2] = newNode2;
    }
}

// 移除边
void removeEdge(struct Graph* graph, int vertex1, int vertex2) {
    if (vertex1 < numVertices && vertex2 < numVertices) {
        struct Node* current = graph->adjList[vertex1];
        struct Node* prev = NULL;
        while (current != NULL) {
            if (current->vertex == vertex2) {
                if (prev == NULL) {
                    graph->adjList[vertex1] = current->next;
                } else {
                    prev->next = current->next;
                }
                free(current);
                break;
            }
            prev = current;
            current = current->next;
        }

        current = graph->adjList[vertex2];
        prev = NULL;
        while (current != NULL) {
            if (current->vertex == vertex1) {
                if (prev == NULL) {
                    graph->adjList[vertex2] = current->next;
                } else {
                    prev->next = current->next;
                }
                free(current);
                break;
            }
            prev = current;
            current = current->next;
        }
    }
}

// 判断边是否存在
bool hasEdge(struct Graph* graph, int vertex1, int vertex2) {
    if (vertex1 < numVertices && vertex2 < numVertices) {
        struct Node* current = graph->adjList[vertex1];
        while (current != NULL) {
            if (current->vertex == vertex2) {
                return true;
            }
                        current = current->next;
        }
    }
    return false;
}

// 获取节点的第一个相邻节点
int firstNeighbor(struct Graph* graph, int vertex) {
    if (vertex < numVertices) {
        struct Node* first = graph->adjList[vertex];
        if (first != NULL) {
            return first->vertex;
        }
    }
    return -1;  // No neighbor found
}

// 获取除指定邻接点外的下一个邻接点
int nextNeighbor(struct Graph* graph, int vertex, int neighbor) {
    if (vertex < numVertices) {
        struct Node* current = graph->adjList[vertex];
        while (current != NULL) {
            if (current->vertex != neighbor) {
                return current->vertex;
            }
            current = current->next;
        }
    }
    return -1;  // No more neighbors
}

int main() {
    // Example usage:
    struct Graph* graph = createGraph();

    insertVertex(graph, 0);
    insertVertex(graph, 1);
    addEdge(graph, 0, 1);
    if (hasEdge(graph, 0, 1)) {
        printf("There is an edge between 0 and 1.\n");
    } else {
        printf("There is no edge between 0 and 1.\n");
    }
    deleteVertex(graph, 1);
    return 0;
}

3.有向图 邻接矩阵

#include <stdio.h>
#include <stdbool.h>
#define MAX_VERTICES 100

int graph[MAX_VERTICES][MAX_VERTICES] = {0};
int numVertices = 0;

void insertVertex(int vertex) {
    if (numVertices < MAX_VERTICES) {
        numVertices++;
    }
}

void deleteVertex(int vertex) {
    if (vertex < numVertices) {
        for (int i = vertex; i < numVertices - 1; i++) {
            for (int j = 0; j < numVertices; j++) {
                graph[i][j] = graph[i + 1][j];
            }
        }
        for (int i = 0; i < numVertices; i++) {
            for (int j = vertex; j < numVertices - 1; j++) {
                graph[i][j] = graph[i][j + 1];
            }
        }
        numVertices--;
    }
}

void addEdge(int start, int end) {
    if (start < numVertices && end < numVertices) {
        graph[start][end] = 1;
    }
}

void removeEdge(int start, int end) {
    if (start < numVertices && end < numVertices) {
        graph[start][end] = 0;
    }
}

bool hasEdge(int start, int end) {
    if (start < numVertices && end < numVertices) {
        return graph[start][end] != 0;
    }
    return false;
}

int firstNeighbor(int vertex) {
    if (vertex < numVertices) {
        for (int i = 0; i < numVertices; i++) {
            if (graph[vertex][i] != 0) {
                return i;
            }
        }
    }
    return -1;  // No neighbor found
}

int nextNeighbor(int vertex, int neighbor) {
    if (vertex < numVertices && neighbor < numVertices) {
        for (int i = neighbor + 1; i < numVertices; i++) {
            if (graph[vertex][i] != 0) {
                return i;
            }
        }
    }
    return -1;  // No more neighbors
}

int main() {
    // Example usage:
    insertVertex(0);
    insertVertex(1);
    addEdge(0, 1);

    if (hasEdge(0, 1)) {
        printf("There is an edge between 0 and 1.\n");
    } else {
        printf("There is no edge between 0 and 1.\n");
    }
    deleteVertex(1);
    return 0;
}

4.有向图 邻接表

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MaxVertexNum 100

typedef struct ArcNode {    //边表节点
    int adjvex;              // 该弧指向顶点的位置
    struct ArcNode* next;   // 指向下一条弧的指针
    // int info;     // 网的边权值
} ArcNode;

typedef struct VNode {
    int data;          // 顶点信息
    ArcNode* first;    // 指向第一条依附该节点的弧的指针
} VNode, AdjList[MaxVertexNum];

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

// 初始化有向图
void initGraph(ALGraph* graph, int numVertices) {
    graph->vexnum = numVertices;
    graph->arcnum = 0;  // 初始化时没有边

    for (int i = 0; i < numVertices; i++) {
        graph->vertices[i].data = i;  // 假设顶点的数据就是它的索引
        graph->vertices[i].first = NULL;
    }
}

// 添加有向边
void addEdge(ALGraph* graph, int start, int end) {
    if (start >= 0 && start < graph->vexnum && end >= 0 && end < graph->vexnum) {
        ArcNode* newNode = (ArcNode*)malloc(sizeof(ArcNode));
        newNode->adjvex = end;
        newNode->next = graph->vertices[start].first;
        graph->vertices[start].first = newNode;
        graph->arcnum++;
    }
}

// 删除有向边
void removeEdge(ALGraph* graph, int start, int end) {
    if (start >= 0 && start < graph->vexnum) {
        ArcNode* current = graph->vertices[start].first;
        ArcNode* prev = NULL;
        while (current != NULL) {
            if (current->adjvex == end) {
                if (prev == NULL) {
                    graph->vertices[start].first = current->next;
                } else {
                    prev->next = current->next;
                }
                free(current);
                graph->arcnum--;
                break;
            }
            prev = current;
            current = current->next;
        }
    }
}

// 判断有向边是否存在
bool hasEdge(ALGraph* graph, int start, int end) {
    if (start >= 0 && start < graph->vexnum) {
        ArcNode* current = graph->vertices[start].first;
        while (current != NULL) {
            if (current->adjvex == end) {
                return true;
            }
            current = current->next;
        }
    }
    return false;
}

int main() {
    ALGraph graph;
    int numVertices = 5;  // 假设有5个顶点
    initGraph(&graph, numVertices);

    addEdge(&graph, 0, 1);
    addEdge(&graph, 0, 2);
    addEdge(&graph, 1, 3);

    printf("Number of vertices: %d\n", graph.vexnum);
    printf("Number of edges: %d\n", graph.arcnum);

    if (hasEdge(&graph, 0, 1)) {
        printf("There is an edge from 0 to 1.\n");
    } else {
        printf("There is no edge from 0 to 1.\n");
    }
    removeEdge(&graph, 0, 1);
    return 0;
}

5.无向图 邻接表 广度优先搜索

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define MaxVertexNum 100
#define QUEUE_SIZE MaxVertexNum

typedef struct {
    int Vex[MaxVertexNum];
    int Edge[MaxVertexNum][MaxVertexNum];
    int vexnum, arcnum;
} MGraph;

// 初始化无向图
void initGraph(MGraph* graph, int numVertices) {
    graph->vexnum = numVertices;
    graph->arcnum = 0;

    // 初始化图的边矩阵
    for (int i = 0; i < numVertices; i++) {
        for (int j = 0; j < numVertices; j++) {
            graph->Edge[i][j] = 0;
        }
    }
}

// 添加无向边
void addEdge(MGraph* graph, int vertex1, int vertex2) {
    if (vertex1 >= 0 && vertex1 < graph->vexnum && vertex2 >= 0 && vertex2 < graph->vexnum) {
        graph->Edge[vertex1][vertex2] = 1;
        graph->Edge[vertex2][vertex1] = 1;
        graph->arcnum++;
    }
}

// 队列结构
typedef struct {
    int data[QUEUE_SIZE];
    int front, rear;
} Queue;

// 初始化队列
void initQueue(Queue* q) {
    q->front = q->rear = -1;
}

// 入队列
void enqueue(Queue* q, int value) {
    if (q->rear == QUEUE_SIZE - 1) {
        printf("Queue is full.\n");
        return;
    }
    if (q->front == -1) {
        q->front = 0;
    }
    q->rear++;
    q->data[q->rear] = value;
}

// 出队列
int dequeue(Queue* q) {
    if (q->front == -1) {
        printf("Queue is empty.\n");
        return -1;
    }
    int value = q->data[q->front];
    if (q->front == q->rear) {
        q->front = q->rear = -1;
    } else {
        q->front++;
    }
    return value;
}

// 访问标记数组
bool visited[MaxVertexNum] = { false };

// 全局队列变量
Queue queue;

// 广度优先搜索
void BFS(MGraph* graph, int start) {
    visited[start] = true;
    printf("%d ", start);
    enqueue(&queue, start);

    while (queue.front != -1) {
        int current = dequeue(&queue);
        // 遍历当前顶点的所有邻接顶点
        for (int i = 0; i < graph->vexnum; i++) {
            // 如果有边连接且未被访问
            if (graph->Edge[current][i] == 1 && !visited[i]) {
                visited[i] = true; // 标记为已访问
                printf("%d ", i); // 输出顶点
                enqueue(&queue, i); // 入队列
            }
        }
    }
}

// 遍历所有连通分量的BFS
void BFSTraverse(MGraph* graph) {
    // 遍历所有顶点,确保每个连通分量都被访问到
    for (int i = 0; i < graph->vexnum; i++) {
        if (!visited[i]) {
            printf("从节点%d开始:",i);       //可以注释掉 方便看进行几次bfs
            BFS(graph, i);
            printf("\n");
        }
    }
}

int main() {
    MGraph graph;
    int numVertices = 6;  // 假设有6个顶点

    initGraph(&graph, numVertices);

    addEdge(&graph, 0, 1);
    addEdge(&graph, 0, 2);
    addEdge(&graph, 1, 3);
    addEdge(&graph, 4, 5);
    initQueue(&queue); // 初始化队列
    BFSTraverse(&graph); // 执行广度优先搜索
    return 0;
}

6.有向图 邻接矩阵 深度优先搜索

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

#define MaxVertexNum 100

// 有向图的邻接表结构
typedef struct ArcNode {
    int adjvex;                // 邻接点的下标
    struct ArcNode* nextarc;  // 指向下一个邻接点的指针
} ArcNode;

typedef struct VNode {
    // 顶点的其他信息(如果有)
    ArcNode* firstarc;  // 指向第一个邻接点的指针
} VNode;

typedef struct {
    VNode adjlist[MaxVertexNum];  // 顶点数组,存储有向图的邻接表
    int vexnum, arcnum;           // 顶点数和弧数
} ALGraph;

// 初始化有向图
void InitGraph(ALGraph* graph, int numVertices) {
    graph->vexnum = numVertices;
    graph->arcnum = 0;

    // 初始化邻接表
    for (int i = 0; i < numVertices; i++) {
        graph->adjlist[i].firstarc = NULL;
    }
}

// 添加有向边
void AddEdge(ALGraph* graph, int start, int end) {
    if (start >= 0 && start < graph->vexnum && end >= 0 && end < graph->vexnum) {
        ArcNode* newArc = (ArcNode*)malloc(sizeof(ArcNode));
        newArc->adjvex = end;
        newArc->nextarc = graph->adjlist[start].firstarc;
        graph->adjlist[start].firstarc = newArc;
        graph->arcnum++;
    }
}

// 访问标记数组
bool visited[MaxVertexNum] = { false };

// 深度优先搜索
void DFS(ALGraph* graph, int v) {
    visited[v] = true;
    printf("%d ", v);

    ArcNode* currentArc = graph->adjlist[v].firstarc;
    while (currentArc != NULL) {
        int adjvex = currentArc->adjvex;
        if (!visited[adjvex]) {
            DFS(graph, adjvex);
        }
        currentArc = currentArc->nextarc;
    }
}

// 遍历所有连通分量的DFS
void DFSTraverse(ALGraph* graph) {
    for (int i = 0; i < graph->vexnum; i++) {
        visited[i] = false; // 初始化访问标记数组
    }

    for (int i = 0; i < graph->vexnum; i++) {
        if (!visited[i]) {
            printf("从节点 %d 开始: ", i);
            DFS(graph, i);
            printf("\n");
        }
    }
}

int main() {
    ALGraph graph;
    int numVertices = 6;  // 假设有6个顶点

    InitGraph(&graph, numVertices);
    AddEdge(&graph, 0, 1);
    AddEdge(&graph, 1, 2);
    AddEdge(&graph, 2, 0);
    AddEdge(&graph, 3, 4);
    AddEdge(&graph, 4, 5);

    DFSTraverse(&graph); // 执行深度优先搜索
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值