
🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会!
📙C 语言百万年薪修炼课程 【https://dwz.mosong.cc/cyyjc】通俗易懂,深入浅出,匠心打磨,死磕细节,6年迭代,看过的人都说好。


在 C 语言中,实现图结构是一项重要且具有挑战性的任务。图是一种复杂的数据结构,用于表示对象之间的关系。它由顶点(Vertex)和边(Edge)组成,可以分为有向图和无向图两种类型。
在 C 语言中,常见的图表示方法有邻接矩阵(Adjacency Matrix)和邻接表(Adjacency List)。
邻接矩阵是一个二维数组,用于表示图中顶点之间的连接关系。如果顶点 i 和顶点 j 之间有边相连,则矩阵中的 [i][j] 元素为 1(或边的权值);否则为 0。
以下是使用邻接矩阵表示无向图的 C 语言示例代码:
#include'#include #define V 5 // 顶点数量 // 打印邻接矩阵 void printAdjMatrix(int adjMatrix[V][V]) { for (int i = 0; i < V; i++) { for (int j = 0; j < V; j++) { printf("%d ", adjMatrix[i][j]); } printf("\n"); } } int main() { int adjMatrix[V][V] = { {0, 1, 0, 1, 0}, {1, 0, 1, 0, 1}, {0, 1, 0, 1, 0}, {1, 0, 1, 0, 1}, {0, 1, 0, 1, 0} }; printf("邻接矩阵表示的无向图:\n"); printAdjMatrix(adjMatrix); return 0; } 运行
邻接矩阵的优点是直观、简单,判断两个顶点之间是否有边的时间复杂度为 O(1)。但对于稀疏图(边的数量相对较少),会浪费大量的存储空间。
邻接表是一种链表数组,每个数组元素是一个链表,链表中存储与该顶点相连的其他顶点。
以下是使用邻接表表示无向图的 C 语言示例代码:
#include'#include // 图的顶点结构体 typedef struct Vertex { int data; struct Vertex* next; } Vertex; // 创建新的顶点 Vertex* createVertex(int data) { Vertex* newVertex = (Vertex*)malloc(sizeof(Vertex)); newVertex->data = data; newVertex->next = NULL; return newVertex; } // 向邻接表中添加边 void addEdge(Vertex* adjList[], int src, int dest) { Vertex* newNode = createVertex(dest); newNode->next = adjList[src]; adjList[src] = newNode; newNode = createVertex(src); newNode->next = adjList[dest]; adjList[dest] = newNode; } // 打印邻接表 void printAdjList(Vertex* adjList[], int V) { for (int i = 0; i < V; i++) { Vertex* temp = adjList[i]; printf("顶点 %d: ", i); while (temp) { printf("%d -> ", temp->data); temp = temp->next; } printf("NULL\n"); } } int main() { int V = 5; // 顶点数量 Vertex* adjList[V]; for (int i = 0; i < V; i++) { adjList[i] = NULL; } addEdge(adjList, 0, 1); addEdge(adjList, 0, 4); addEdge(adjList, 1, 2); addEdge(adjList, 1, 3); addEdge(adjList, 1, 4); addEdge(adjList, 2, 3); addEdge(adjList, 3, 4); printf("邻接表表示的无向图:\n"); printAdjList(adjList, V); return 0; } 运行
邻接表的优点是节省存储空间,适用于稀疏图。但查找两个顶点之间是否有边的时间复杂度相对较高。
图的遍历是指按照一定的顺序访问图中的所有顶点。常见的图遍历算法有深度优先搜索(Depth-First Search,DFS)和广度优先搜索(Breadth-First Search,BFS)。
深度优先搜索从起始顶点开始,沿着一条路径尽可能深地访问顶点,直到无法继续,然后回溯到上一个未完全探索的顶点,继续探索其他路径。
以下是使用递归方式实现深度优先搜索的 C 语言示例代码:
#include'#include #define V 5 // 顶点数量 // 邻接矩阵 int adjMatrix[V][V] = { {0, 1, 0, 1, 0}, {1, 0, 1, 0, 1}, {0, 1, 0, 1, 0}, {1, 0, 1, 0, 1}, {0, 1, 0, 1, 0} }; // 用于标记顶点是否已被访问 int visited[V] = {0}; // 深度优先搜索递归函数 void DFS(int v) { visited[v] = 1; printf("%d ", v); for (int i = 0; i < V; i++) { if (adjMatrix[v][i] == 1 && visited[i] == 0) { DFS(i); } } } int main() { printf("深度优先搜索的结果: "); DFS(0); return 0; } 运行
广度优先搜索从起始顶点开始,先访问其所有相邻顶点,然后依次访问这些相邻顶点的相邻顶点,依此类推。
以下是使用队列实现广度优先搜索的 C 语言示例代码:
#include'#include #define V 5 // 顶点数量 // 邻接矩阵 int adjMatrix[V][V] = { {0, 1, 0, 1, 0}, {1, 0, 1, 0, 1}, {0, 1, 0, 1, 0}, {1, 0, 1, 0, 1}, {0, 1, 0, 1, 0} }; // 用于标记顶点是否已被访问 int visited[V] = {0}; // 队列结构体 typedef struct Queue { int* items; int front; int rear; } Queue; // 创建队列 Queue* createQueue(int size) { Queue* queue = (Queue*)malloc(sizeof(Queue)); queue->items = (int*)malloc(size * sizeof(int)); queue->front = -1; queue->rear = -1; return queue; } // 判断队列是否为空 int isEmpty(Queue* queue) { return queue->front == -1; } // 判断队列是否已满 int isFull(Queue* queue, int size) { return (queue->rear + 1) % size == queue->front; } // 入队 void enqueue(Queue* queue, int item) { if (isFull(queue, V)) { printf("队列已满\n"); return; } if (isEmpty(queue)) { queue->front = 0; } queue->rear = (queue->rear + 1) % V; queue->items[queue->rear] = item; } // 出队 int dequeue(Queue* queue) { int item; if (isEmpty(queue)) { printf("队列为空\n"); return -1; } item = queue->items[queue->front]; if (queue->front == queue->rear) { queue->front = -1; queue->rear = -1; } else { queue->front = (queue->front + 1) % V; } return item; } // 广度优先搜索函数 void BFS(int start) { Queue* queue = createQueue(V); visited[start] = 1; printf("%d ", start); enqueue(queue, start); while (!isEmpty(queue)) { int current = dequeue(queue); for (int i = 0; i < V; i++) { if (adjMatrix[current][i] == 1 && visited[i] == 0) { visited[i] = 1; printf("%d ", i); enqueue(queue, i); } } } free(queue->items); free(queue); } int main() { printf("广度优先搜索的结果: "); BFS(0); return 0; } 运行
图在计算机科学中有广泛的应用,以下是一些常见的应用场景:
在计算机网络中,图可以用于表示网络拓扑结构,通过图算法找到最优的路由路径。
分析社交网络中人与人之间的关系,例如找出朋友关系中的社群结构。
在操作系统中,安排任务的执行顺序和资源分配。
地图可以被看作是一个图,通过图算法找到最短路径或最优路径。
在 C 语言中实现图结构需要对图的基本概念有清晰的理解,选择合适的表示方法(邻接矩阵或邻接表),并掌握图的遍历算法(深度优先搜索和广度优先搜索)。根据具体的应用场景和图的特点,选择最优的实现方式和算法,以提高程序的效率和性能。

🎉相关推荐
