模仿:
algorithm-journey/src/class059/Code01_CreateGraph.java at main · algorithmzuo/algorithm-journey
Code01_CreateGraph
C语言:
cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 11
#define MAXM 21
// 邻接矩阵
int graph1[MAXN][MAXN];
// 邻接表
typedef struct EdgeNode {
int to;
int weight;
struct EdgeNode* next;
} EdgeNode;
EdgeNode* graph2[MAXN];
// 链式前向星
int head[MAXN];
int next[MAXM];
int to[MAXM];
int weight[MAXM];
int cnt;
// 初始化图
void build(int n) {
// 邻接矩阵初始化
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
graph1[i][j] = 0;
}
}
// 邻接表初始化
for (int i = 0; i <= n; i++) {
graph2[i] = NULL;
}
// 链式前向星初始化
cnt = 1;
memset(head, 0, sizeof(head));
}
// 链式前向星添加边
void addEdge(int u, int v, int w) {
next[cnt] = head[u];
to[cnt] = v;
weight[cnt] = w;
head[u] = cnt++;
}
// 添加邻接表边
void addAdjListEdge(int u, int v, int w) {
EdgeNode* newNode = (EdgeNode*)malloc(sizeof(EdgeNode));
newNode->to = v;
newNode->weight = w;
newNode->next = graph2[u];
graph2[u] = newNode;
}
// 有向图构建
void directGraph(int edges[][3], int edgeCount) {
// 邻接矩阵
for (int i = 0; i < edgeCount; i++) {
graph1[edges[i][0]][edges[i][1]] = edges[i][2];
}
// 邻接表
for (int i = 0; i < edgeCount; i++) {
addAdjListEdge(edges[i][0], edges[i][1], edges[i][2]);
}
// 链式前向星
for (int i = 0; i < edgeCount; i++) {
addEdge(edges[i][0], edges[i][1], edges[i][2]);
}
}
// 无向图构建
void undirectGraph(int edges[][3], int edgeCount) {
// 邻接矩阵
for (int i = 0; i < edgeCount; i++) {
graph1[edges[i][0]][edges[i][1]] = edges[i][2];
graph1[edges[i][1]][edges[i][0]] = edges[i][2];
}
// 邻接表
for (int i = 0; i < edgeCount; i++) {
addAdjListEdge(edges[i][0], edges[i][1], edges[i][2]);
addAdjListEdge(edges[i][1], edges[i][0], edges[i][2]);
}
// 链式前向星
for (int i = 0; i < edgeCount; i++) {
addEdge(edges[i][0], edges[i][1], edges[i][2]);
addEdge(edges[i][1], edges[i][0], edges[i][2]);
}
}
// 遍历图
void traversal(int n) {
printf("邻接矩阵遍历 :\n");
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
printf("%d ", graph1[i][j]);
}
printf("\n");
}
printf("邻接表遍历 :\n");
for (int i = 1; i <= n; i++) {
printf("%d(邻居、边权) : ", i);
EdgeNode* current = graph2[i];
while (current != NULL) {
printf("(%d,%d) ", current->to, current->weight);
current = current->next;
}
printf("\n");
}
printf("链式前向星 :\n");
for (int i = 1; i <= n; i++) {
printf("%d(邻居、边权) : ", i);
for (int ei = head[i]; ei > 0; ei = next[ei]) {
printf("(%d,%d) ", to[ei], weight[ei]);
}
printf("\n");
}
}
// 释放邻接表内存
void freeAdjList(int n) {
for (int i = 1; i <= n; i++) {
EdgeNode* current = graph2[i];
while (current != NULL) {
EdgeNode* temp = current;
current = current->next;
free(temp);
}
}
}
int main() {
// 有向图示例
int n1 = 4;
int edges1[][3] = { {1, 3, 6}, {4, 3, 4}, {2, 4, 2}, {1, 2, 7}, {2, 3, 5}, {3, 1, 1} };
build(n1);
directGraph(edges1, 6);
traversal(n1);
freeAdjList(n1);
printf("==============================\n");
// 无向图示例
int n2 = 5;
int edges2[][3] = { {3, 5, 4}, {4, 1, 1}, {3, 4, 2}, {5, 2, 4}, {2, 3, 7}, {1, 5, 5}, {4, 2, 6} };
build(n2);
undirectGraph(edges2, 7);
traversal(n2);
freeAdjList(n2);
return 0;
}
C++版本:
cpp
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int MAXN = 11;
const int MAXM = 21;
// 邻接矩阵
int graph1[MAXN][MAXN];
// 邻接表
struct Edge {
int to;
int weight;
};
vector<Edge> graph2[MAXN];
// 链式前向星
int head[MAXN];
int next[MAXM];
int to[MAXM];
int weight[MAXM];
int cnt;
// 初始化图
void build(int n) {
// 邻接矩阵初始化
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
graph1[i][j] = 0;
}
}
// 邻接表初始化
for (int i = 0; i <= n; i++) {
graph2[i].clear();
}
// 链式前向星初始化
cnt = 1;
memset(head, 0, sizeof(head));
}
// 链式前向星添加边
void addEdge(int u, int v, int w) {
next[cnt] = head[u];
to[cnt] = v;
weight[cnt] = w;
head[u] = cnt++;
}
// 有向图构建
void directGraph(vector<vector<int>> edges) {
// 邻接矩阵
for (auto edge : edges) {
graph1[edge[0]][edge[1]] = edge[2];
}
// 邻接表
for (auto edge : edges) {
graph2[edge[0]].push_back({edge[1], edge[2]});
}
// 链式前向星
for (auto edge : edges) {
addEdge(edge[0], edge[1], edge[2]);
}
}
// 无向图构建
void undirectGraph(vector<vector<int>> edges) {
// 邻接矩阵
for (auto edge : edges) {
graph1[edge[0]][edge[1]] = edge[2];
graph1[edge[1]][edge[0]] = edge[2];
}
// 邻接表
for (auto edge : edges) {
graph2[edge[0]].push_back({edge[1], edge[2]});
graph2[edge[1]].push_back({edge[0], edge[2]});
}
// 链式前向星
for (auto edge : edges) {
addEdge(edge[0], edge[1], edge[2]);
addEdge(edge[1], edge[0], edge[2]);
}
}
// 遍历图
void traversal(int n) {
cout << "邻接矩阵遍历 :" << endl;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << graph1[i][j] << " ";
}
cout << endl;
}
cout << "邻接表遍历 :" << endl;
for (int i = 1; i <= n; i++) {
cout << i << "(邻居、边权) : ";
for (auto edge : graph2[i]) {
cout << "(" << edge.to << "," << edge.weight << ") ";
}
cout << endl;
}
cout << "链式前向星 :" << endl;
for (int i = 1; i <= n; i++) {
cout << i << "(邻居、边权) : ";
for (int ei = head[i]; ei > 0; ei = next[ei]) {
cout << "(" << to[ei] << "," << weight[ei] << ") ";
}
cout << endl;
}
}
int main() {
// 有向图示例
int n1 = 4;
vector<vector<int>> edges1 = { {1, 3, 6}, {4, 3, 4}, {2, 4, 2}, {1, 2, 7}, {2, 3, 5}, {3, 1, 1} };
build(n1);
directGraph(edges1);
traversal(n1);
cout << "==============================" << endl;
// 无向图示例
int n2 = 5;
vector<vector<int>> edges2 = { {3, 5, 4}, {4, 1, 1}, {3, 4, 2}, {5, 2, 4}, {2, 3, 7}, {1, 5, 5}, {4, 2, 6} };
build(n2);
undirectGraph(edges2);
traversal(n2);
return 0;
}
Code02_TopoSortDynamicLeetcode
C版本:
cpp
#include <stdio.h>
#include <stdlib.h>
// 定义邻接表节点结构
typedef struct Node {
int vertex;
struct Node* next;
} Node;
// 添加新节点到邻接表
Node* addNode(int v) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->vertex = v;
newNode->next = NULL;
return newNode;
}
int* findOrder(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize, int* returnSize) {
// 创建邻接表
Node** graph = (Node**)malloc(numCourses * sizeof(Node*));
for (int i = 0; i < numCourses; i++) {
graph[i] = NULL;
}
// 创建入度表
int* indegree = (int*)calloc(numCourses, sizeof(int));
// 构建图和入度表
for (int i = 0; i < prerequisitesSize; i++) {
int ai = prerequisites[i][0];
int bi = prerequisites[i][1];
Node* newNode = addNode(ai);
newNode->next = graph[bi];
graph[bi] = newNode;
indegree[ai]++;
}
// 创建队列
int* queue = (int*)malloc(numCourses * sizeof(int));
int l = 0, r = 0;
// 将入度为0的节点入队
for (int i = 0; i < numCourses; i++) {
if (indegree[i] == 0) {
queue[r++] = i;
}
}
// 拓扑排序
int cnt = 0;
while (l < r) {
int cur = queue[l++];
cnt++;
Node* temp = graph[cur];
while (temp != NULL) {
int next = temp->vertex;
if (--indegree[next] == 0) {
queue[r++] = next;
}
temp = temp->next;
}
}
// 释放内存
for (int i = 0; i < numCourses; i++) {
Node* temp = graph[i];
while (temp != NULL) {
Node* next = temp->next;
free(temp);
temp = next;
}
}
free(graph);
free(indegree);
// 返回结果
if (cnt == numCourses) {
*returnSize = numCourses;
return queue;
} else {
*returnSize = 0;
free(queue);
return NULL;
}
}
C++版本:
cpp
#include <vector>
#include <queue>
using namespace std;
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
// 创建邻接表
vector<vector<int>> graph(numCourses);
// 创建入度表
vector<int> indegree(numCourses, 0);
// 构建图和入度表
for (const auto& edge : prerequisites) {
int ai = edge[0];
int bi = edge[1];
graph[bi].push_back(ai);
indegree[ai]++;
}
// 创建队列
queue<int> q;
// 将入度为0的节点入队
for (int i = 0; i < numCourses; i++) {
if (indegree[i] == 0) {
q.push(i);
}
}
// 拓扑排序
vector<int> result;
int cnt = 0;
while (!q.empty()) {
int cur = q.front();
q.pop();
result.push_back(cur);
cnt++;
for (int next : graph[cur]) {
if (--indegree[next] == 0) {
q.push(next);
}
}
}
// 返回结果
if (cnt == numCourses) {
return result;
} else {
return {};
}
}