C语言图结构学习笔记

news2025/2/24 15:24:34

1. 图的定义

图(Graph)是一种数据结构,由顶点(Vertex)和边(Edge)组成,用于表示对象及其相互关系。图可以是有向图(Directed Graph)或无向图(Undirected Graph)。

1.1 有向图

有向图的边有方向,表示顶点之间的单向关系。

A → B

1.2 无向图

无向图的边没有方向,表示顶点之间的双向关系。

A — B

2. 图的表示方法

2.1 邻接矩阵

邻接矩阵是一种二维数组,用于表示顶点之间的连接关系。

#define MAX_VERTICES 100
int adjMatrix[MAX_VERTICES][MAX_VERTICES];

2.2 邻接表

邻接表是一种链表数组,每个链表表示一个顶点及其相邻顶点。

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

typedef struct AdjNode {
    int vertex;
    struct AdjNode* next;
} AdjNode;

typedef struct {
    AdjNode* head;
} AdjList;

typedef struct {
    int numVertices;
    AdjList* list;
} Graph;

Graph* createGraph(int vertices) {
    Graph* graph = (Graph*)malloc(sizeof(Graph));
    graph->numVertices = vertices;
    graph->list = (AdjList*)malloc(vertices * sizeof(AdjList));
    for (int i = 0; i < vertices; i++) {
        graph->list[i].head = NULL;
    }
    return graph;
}

void addEdge(Graph* graph, int src, int dest) {
    AdjNode* newNode = (AdjNode*)malloc(sizeof(AdjNode));
    newNode->vertex = dest;
    newNode->next = graph->list[src].head;
    graph->list[src].head = newNode;

    newNode = (AdjNode*)malloc(sizeof(AdjNode));
    newNode->vertex = src;
    newNode->next = graph->list[dest].head;
    graph->list[dest].head = newNode;
}

3. 图的遍历

3.1 深度优先搜索(DFS)

深度优先搜索是一种图遍历算法,从一个顶点出发,沿着边尽可能深入地访问顶点,直到不能再深入为止,然后回溯到上一个顶点继续访问。

void DFS(Graph* graph, int vertex, int* visited) {
    visited[vertex] = 1;
    printf("%d ", vertex);
    AdjNode* adjList = graph->list[vertex].head;
    while (adjList != NULL) {
        int connectedVertex = adjList->vertex;
        if (!visited[connectedVertex]) {
            DFS(graph, connectedVertex, visited);
        }
        adjList = adjList->next;
    }
}

3.2 广度优先搜索(BFS)

广度优先搜索是一种图遍历算法,从一个顶点出发,先访问所有相邻顶点,然后再访问这些相邻顶点的相邻顶点,依次类推。

#include <stdbool.h>
#include <limits.h>

void BFS(Graph* graph, int startVertex) {
    int visited[MAX_VERTICES];
    for (int i = 0; i < graph->numVertices; i++) {
        visited[i] = 0;
    }
    int queue[MAX_VERTICES];
    int front = 0, rear = 0;

    visited[startVertex] = 1;
    queue[rear++] = startVertex;

    while (front < rear) {
        int currentVertex = queue[front++];
        printf("%d ", currentVertex);
        AdjNode* adjList = graph->list[currentVertex].head;
        while (adjList != NULL) {
            int connectedVertex = adjList->vertex;
            if (!visited[connectedVertex]) {
                visited[connectedVertex] = 1;
                queue[rear++] = connectedVertex;
            }
            adjList = adjList->next;
        }
    }
}

4. 最短路径算法

4.1 Dijkstra算法

Dijkstra算法用于计算从单个源顶点到所有其他顶点的最短路径。

#include <stdio.h>

#define INF INT_MAX

void dijkstra(int graph[MAX_VERTICES][MAX_VERTICES], int n, int startVertex) {
    int distance[MAX_VERTICES], visited[MAX_VERTICES];
    for (int i = 0; i < n; i++) {
        distance[i] = INF;
        visited[i] = 0;
    }
    distance[startVertex] = 0;
    for (int i = 0; i < n - 1; i++) {
        int minDistance = INF, minIndex;
        for (int j = 0; j < n; j++) {
            if (!visited[j] && distance[j] <= minDistance) {
                minDistance = distance[j];
                minIndex = j;
            }
        }
        visited[minIndex] = 1;
        for (int j = 0; j < n; j++) {
            if (!visited[j] && graph[minIndex][j] && distance[minIndex] != INF && distance[minIndex] + graph[minIndex][j] < distance[j]) {
                distance[j] = distance[minIndex] + graph[minIndex][j];
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("Distance from %d to %d: %d\n", startVertex, i, distance[i]);
    }
}

5. 最小生成树算法

5.1 Prim算法

Prim算法用于找到一个加权无向图的最小生成树。

void prim(int graph[MAX_VERTICES][MAX_VERTICES], int n) {
    int parent[MAX_VERTICES], key[MAX_VERTICES], mstSet[MAX_VERTICES];
    for (int i = 0; i < n; i++) {
        key[i] = INF;
        mstSet[i] = 0;
    }
    key[0] = 0;
    parent[0] = -1;
    for (int count = 0; count < n - 1; count++) {
        int minKey = INF, minIndex;
        for (int v = 0; v < n; v++) {
            if (!mstSet[v] && key[v] < minKey) {
                minKey = key[v];
                minIndex = v;
            }
        }
        mstSet[minIndex] = 1;
        for (int v = 0; v < n; v++) {
            if (graph[minIndex][v] && !mstSet[v] && graph[minIndex][v] < key[v]) {
                parent[v] = minIndex;
                key[v] = graph[minIndex][v];
            }
        }
    }
    for (int i = 1; i < n; i++) {
        printf("Edge: %d - %d, Weight: %d\n", parent[i], i, graph[i][parent[i]]);
    }
}

5.2 Kruskal算法

Kruskal算法用于找到一个加权无向图的最小生成树。

typedef struct {
    int u, v, weight;
} Edge;

int find(int parent[], int i) {
    if (parent[i] == i) {
        return i;
    }
    return find(parent, parent[i]);
}

void unionSets(int parent[], int rank[], int x, int y) {
    int xroot = find(parent, x);
    int yroot = find(parent, y);
    if (rank[xroot] < rank[yroot]) {
        parent[xroot] = yroot;
    } else if (rank[xroot] > rank[yroot]) {
        parent[yroot] = xroot;
    } else {
        parent[yroot] = xroot;
        rank[xroot]++;
    }
}

void kruskal(Edge edges[], int n, int e) {
    int parent[MAX_VERTICES], rank[MAX_VERTICES];
    for (int i = 0; i < n; i++) {
        parent[i] = i;
        rank[i] = 0;
    }
    qsort(edges, e, sizeof(edges[0]), compare);
    int result[MAX_VERTICES][2], resultIndex = 0;
    for (int i = 0; i < e; i++) {
        int u = edges[i].u;
        int v = edges[i].v;
        int setU = find(parent, u);
        int setV = find(parent, v);
        if (setU != setV) {
            result[resultIndex][0] = u;
            result[resultIndex][1] = v;
            resultIndex++;
            unionSets(parent, rank, setU, setV);
        }
    }
    for (int i = 0; i < resultIndex; i++) {
        printf("Edge: %d - %d\n", result[i][0], result[i][1]);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2304453.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记一次复杂分页查询的优化历程:从临时表到普通表的架构演进

1. 问题背景 在项目开发中&#xff0c;我们需要实现一个复杂的分页查询功能&#xff0c;涉及大量 IP 地址数据的处理和多表关联。在我接手这个项目的时候,代码是这样的 要知道代码里面的 ipsList 数据可能几万条甚至更多,这样拼接的sql,必然是要内存溢出的,一味地扩大jvm参数不…

架构师面试(六):熔断和降级

问题 在千万日活的电商系统中&#xff0c;商品列表页服务通过 RPC 调用广告服务&#xff1b;经过统计发现&#xff0c;在最近10秒的时间里&#xff0c;商品列表页服务在对广告服务的调用中有 98% 的调用是超时的&#xff1b; 针对这个场景&#xff0c;下面哪几项的说法是正确的…

细说 Java 引用(强、软、弱、虚)和 GC 流程(二)

一、前文回顾 在 细说Java 引用&#xff08;强、软、弱、虚&#xff09;和 GC 流程&#xff08;一&#xff09; 我们对Java 引用有了总体的认识&#xff0c;本文将继续深入分析 Java 引用在 GC 时的一些细节。 还是从我们在前文中提到的引用流程图里说起&#xff0c;这里不清…

【深度学习】Unet的基础介绍

U-Net是一种用于图像分割的深度学习模型&#xff0c;特别适合医学影像和其他需要分割细节的任务。如图&#xff1a; Unet论文原文 为什么叫U-Net&#xff1f; U-Net的结构像字母“U”&#xff0c;所以得名。它的结构由两个主要部分组成&#xff1a; 下采样&#xff08;编码…

ROS2机器人开发--服务通信与参数通信

服务通信与参数通信 在 ROS 2 中&#xff0c;服务&#xff08;Services&#xff09;通信和参数&#xff08;Parameters&#xff09;通信是两种重要的通信机制。服务是基于请求和响应的双向通信机制。参数用于管理节点的设置&#xff0c;并且参数通信是基于服务通信实现的。 1 …

DeepSeek写贪吃蛇手机小游戏

DeepSeek写贪吃蛇手机小游戏 提问 根据提的要求&#xff0c;让DeepSeek整理的需求&#xff0c;进行提问&#xff0c;内容如下&#xff1a; 请生成一个包含以下功能的可运行移动端贪吃蛇H5文件&#xff1a; 要求 蛇和食物红点要清晰&#xff0c;不超过屏幕外 下方有暂停和重新…

Python安全之反序列化——pickle/cPickle

一&#xff0e; 概述 Python中有两个模块可以实现对象的序列化&#xff0c;pickle和cPickle&#xff0c;区别在于cPickle是用C语言实现的&#xff0c;pickle是用纯python语言实现的&#xff0c;用法类似&#xff0c;cPickle的读写效率高一些。使用时一般先尝试导入cPickle&…

Deepin(Linux)安装MySQL指南

1.下载 地址&#xff1a;https://downloads.mysql.com/archives/community/ 2.将文件解压到 /usr/local 目录下 先cd到安装文件所在目录再解压&#xff0c;本机是cd /home/lu01/Downloads sudo tar -xvJf mysql-9.2.0-linux-glibc2.28-x86_64.tar.xz -C /usr/local3.创建软链…

vue-fastapi-admin 部署心得

vue-fastapi-admin 部署心得 这两天需要搭建一个后台管理系统&#xff0c;找来找去 vue-fastapi-admin 这个开源后台管理框架刚好和我的技术栈所契合。于是就浅浅的研究了一下。 主要是记录如何基于原项目提供的Dockerfile进行调整&#xff0c;那项目文件放在容器外部&#xf…

计算机视觉算法实战——三维重建(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ 1. 三维重建领域简介 三维重建&#xff08;3D Reconstruction&#xff09;是计算机视觉的核心任务之一&#xff0c;旨在通过多视角图像、视频…

迎接DeepSeek开源周[Kimi先开为敬]发布开源最新Muon优化器可替代 AdamW计算效率直接翻倍

Muon优化器在小规模语言模型训练中表现出色&#xff0c;但在大规模模型训练中的可扩展性尚未得到证实。月之暗面通过系统分析和改进&#xff0c;成功将 Muon 应用于 3B/16B 参数的 MoE 模型训练&#xff0c;累计训练 5.7 万亿 token。结果表明&#xff0c;Muon 可以替代 AdamW …

【工作流】Spring Boot 项目与 Camunda 的整合

【工作流】Spring Boot 项目与 Camunda 的整合 【一】Camunda 和主流流程引擎的对比【二】概念介绍【1】Camunda 概念&#xff1a;【2】BPMN 概念 【三】环境准备【1】安装流程设计器CamundaModeler【画图工具】&#xff08;1&#xff09;下载安装 【2】CamundaModeler如何设计…

Grouped-Query Attention(GQA)详解: Pytorch实现

Grouped-Query Attention&#xff08;GQA&#xff09;详解 Grouped-Query Attention&#xff08;GQA&#xff09; 是 Multi-Query Attention&#xff08;MQA&#xff09; 的改进版&#xff0c;它通过在 多个查询头&#xff08;Query Heads&#xff09;之间共享 Key 和 Value&am…

docker基操

docker基操 首先就是安装docker使用docker:创建容器-制作一个镜像-加载镜像首先就是安装docker 随便找一个教程安装就可以,安装过程中主要是不能访问谷歌,下面这篇文章写了镜像的一些问题: 安装docker的网络问题 使用docker:创建容器-制作一个镜像-加载镜像 主要是参考:这篇…

SF-HCI-SAP问题收集1

最近在做HCI的集成&#xff0c;是S4的环境&#xff0c;发现很多东西都跑不通&#xff0c;今天开始收集一下错误点 如果下图冲从0001变成0010&#xff0c;sfiom_rprq_osi表就会存数据&#xff0c;系统检查到此表就会报错&#xff0c;这个选项的作用就是自定义信息类型也能更新&a…

当 OpenAI 不再 open,DeepSeek 如何掀起 AI 开源革命?

开源与闭源的路线之争成为了行业瞩目的焦点&#xff0c;DeepSeek掀起的 AI 开源风暴&#xff01; 一、硅谷“斯普特尼克时刻” 1957年&#xff0c;苏联将人类首颗人造卫星“斯普特尼克”送上太空&#xff0c;美国举国震动。 这颗“篮球”般的卫星&#xff0c;刺痛了自诩科技霸…

论文笔记-WSDM2025-ColdLLM

论文笔记-WSDM2025-Large Language Model Simulator for Cold-Start Recommendation ColdLLM&#xff1a;用于冷启动推荐的大语言模型模拟器摘要1.引言2.前言3.方法3.1整体框架3.1.1行为模拟3.1.2嵌入优化 3.2耦合漏斗ColdLLM3.2.1过滤模拟3.2.2精炼模拟 3.3模拟器训练3.3.1LLM…

基于 Python Django 的校园互助平台(附源码,文档)

博主介绍&#xff1a;✌Java徐师兄、7年大厂程序员经历。全网粉丝13w、csdn博客专家、掘金/华为云等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不…

智慧废品回收小程序php+uniapp

废品回收小程序&#xff1a;数字化赋能环保&#xff0c;开启资源循环新时代 城市垃圾治理难题&#xff0c;废品回收小程序成破局关键 随着城市化进程加速与消费水平提升&#xff0c;我国生活垃圾总量逐年攀升&#xff0c;年均增速达5%-8%&#xff0c;其中超30%为可回收物。然…

网页版的俄罗斯方块

1、新建一个txt文件 2、打开后将代码复制进去保存 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>俄…