Date Structure: Graph

Represent graph structure with adjacency list

Basical Structure

/* ---- 邻接表实现图 ---- */
#pragma once
#include "Head.h"
#include "Stack.h"
#include <iostream>#define MAX_VERTEX_NUM 20// 最大顶点个数
#define VertexType char  //点类型typedef enum
{DG,DN,UDG,UDN
} GraphKind;// 四种图类型typedef struct ArcNode//边结构体
{int adjvex;             // 该弧所指向的顶点的位置struct ArcNode* nextarc;//指向下一条弧的指针int weight;             //权重
} ArcNode;typedef struct VNode//顶点结构体
{VertexType data;  // 顶点信息ArcNode* firstarc;//指向第一条依附该顶点的弧的指针
} VNode, AdjList[MAX_VERTEX_NUM];typedef struct//图结构体
{AdjList vertices;  // 顶点向量int vexnum, arcnum;// 图的当前顶点数和弧数GraphKind Kind;    // 图的种类标志
} ALGraph;

Create

/*---- 几种不同类型的图的构建 ----*/
void CreateALGraph(ALGraph& ALG);void CreateDG(ALGraph& ALG);//构造有向图 Gvoid CreateDN(ALGraph& ALG);//构造有向网 G(即有权的图)void CreateUDG(ALGraph& ALG);//构造无向图 Gvoid CreateUDN(ALGraph& ALG);//构造无向网 G(即有权的图)void CreateALGraph(ALGraph& ALG)
{printf("请输入构造图的类型: \n");std::string temp;std::cin >> temp;if (temp == "DG")ALG.Kind = DG;else if (temp == "DN")ALG.Kind = DN;else if (temp == "UDG")ALG.Kind = UDG;else if (temp == "UDN")ALG.Kind = UDN;switch (ALG.Kind){case DG:CreateDG(ALG);return;//构造有向图 ALGcase DN:CreateDN(ALG);return;//构造有向网 ALG(即有权的图)case UDG:CreateUDG(ALG);return;//构造无向图 ALGcase UDN:CreateUDN(ALG);return;//构造无向网 ALG(即有权的图)}
}//构造有向网 G(即有权的图)
void CreateDN(ALGraph& ALG)
{InitALGraph(ALG);int from, to, value;ArcNode* q;std::cout << "请输入顶点数和边数: \n";std::cin >> ALG.vexnum >> ALG.arcnum;std::cout << "读入顶点信息,建立顶点表: \n";for (int i = 0; i < ALG.vexnum; i++)//读入顶点信息,建立顶点表std::cin >> ALG.vertices[i].data;std::cout << "输入边(Vi,Vj)上的下标i, 下标j, 权w: \n";for (int i = 0; i < ALG.arcnum; i++){std::cin >> from >> to >> value;ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = to;p->weight = value;p->nextarc = NULL;if (ALG.vertices[from].firstarc){for (q = ALG.vertices[from].firstarc; q->nextarc; q = q->nextarc);q->nextarc = p;}elseALG.vertices[from].firstarc = p;}
}//构造有向图 G
void CreateDG(ALGraph& ALG)
{InitALGraph(ALG);int from, to;ArcNode* q;std::cout << "请输入顶点数和边数: \n";std::cin >> ALG.vexnum >> ALG.arcnum;std::cout << "读入顶点信息,建立顶点表: \n";for (int i = 0; i < ALG.vexnum; i++)//读入顶点信息,建立顶点表std::cin >> ALG.vertices[i].data;std::cout << "输入边(Vi,Vj)上的下标i, 下标j\n";for (int i = 0; i < ALG.arcnum; i++){std::cin >> from >> to;ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = to;p->weight = 1;//单纯的有向图权重为1, 表示这两个顶点是连接着的.p->nextarc = NULL;if (ALG.vertices[from].firstarc){for (q = ALG.vertices[from].firstarc; q->nextarc; q = q->nextarc);q->nextarc = p;}elseALG.vertices[from].firstarc = p;}
}//构造无向图 G, 通过测试
void CreateUDG(ALGraph& ALG)
{InitALGraph(ALG);int from, to;ArcNode* q;std::cout << "请输入顶点数和边数: \n";std::cin >> ALG.vexnum >> ALG.arcnum;std::cout << "读入顶点信息,建立顶点表: \n";for (int i = 0; i < ALG.vexnum; i++)//读入顶点信息,建立顶点表std::cin >> ALG.vertices[i].data;std::cout << "输入边(Vi,Vj)上的下标i, 下标j\n";for (int i = 0; i < ALG.arcnum; i++){std::cin >> from >> to;ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = to;p->weight = 1;//单纯的有向图权重为1, 表示这两个顶点是连接着的.p->nextarc = nullptr;if (ALG.vertices[from].firstarc){for (q = ALG.vertices[from].firstarc; q->nextarc; q = q->nextarc);q->nextarc = p;}elseALG.vertices[from].firstarc = p;p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = from;p->weight = 1;p->nextarc = nullptr;if (ALG.vertices[to].firstarc){for (q = ALG.vertices[to].firstarc; q->nextarc; q = q->nextarc);q->nextarc = p;}elseALG.vertices[to].firstarc = p;}
}//构造无向网 G(即有权的图)
void CreateUDN(ALGraph& ALG)
{InitALGraph(ALG);int from, to, value;ArcNode* q;std::cout << "请输入顶点数和边数: \n";std::cin >> ALG.vexnum >> ALG.arcnum;std::cout << "读入顶点信息,建立顶点表: \n";for (int i = 0; i < ALG.vexnum; i++)//读入顶点信息,建立顶点表std::cin >> ALG.vertices[i].data;std::cout << "输入边(Vi,Vj)上的下标i, 下标j, 权w: \n";for (int i = 0; i < ALG.arcnum; i++){std::cin >> from >> to >> value;ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = to;p->weight = value;p->nextarc = NULL;if (ALG.vertices[from].firstarc){for (q = ALG.vertices[from].firstarc; q->nextarc; q = q->nextarc);q->nextarc = p;}elseALG.vertices[from].firstarc = p;p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = from;p->weight = value;p->nextarc = NULL;if (ALG.vertices[to].firstarc){for (q = ALG.vertices[to].firstarc; q->nextarc; q = q->nextarc);q->nextarc = p;}elseALG.vertices[to].firstarc = p;}
}

Predecessor-free vertex-first algorithm

/* ---- [无前趋的顶点优先算法] ---- */
void FindInDegree(ALGraph ALG, int indegree[]);void FindOutDegree(ALGraph ALG, int outdegree[]);int TopologicalSort(ALGraph ALG);//计算各个节点的入度
void FindInDegree(ALGraph ALG, int indegree[])
{ArcNode* q;for (int i = 0; i < ALG.vexnum; i++)for (q = ALG.vertices[i].firstarc; q; q = q->nextarc)indegree[q->adjvex]++;
}//计算各个顶点的出度
void FindOutDegree(ALGraph ALG, int outdegree[])
{ArcNode* q;for (int i = 0; i < ALG.vexnum; i++)for (q = ALG.vertices[i].firstarc; q; q = q->nextarc)outdegree[i]++;
}//无前趋的顶点优先算法
int TopologicalSort(ALGraph ALG)
{int indegree[MAX_VERTEX_NUM] = {0};FindInDegree(ALG, indegree);//求各顶点入度
#if TEST//检查计算各个顶点的入度是否正确printf("检查入度是否正确: \n") for (int i = 0; i < ALG.vexnum; i++)std::cout<< ALG.vertices[i].data << " " << indegree[i] << std::endl;printf("\n");
#endifSqStack<int> S{};InitStack(S);for (int i = 0; i < ALG.vexnum; i++)if (!indegree[i])Push(S, i);//如果某个顶点的入度为0, 将其入栈int temp;int count = 0;while (!StackEmpty(S)){Pop(S, temp);
#if TESTprintf("顶点编号: %d 顶点值: %c\n", temp, ALG.vertices[temp].data);
#endif++count;for (ArcNode* p = ALG.vertices[temp].firstarc; p; p = p->nextarc){temp = p->adjvex;       //修改入度if (!(--indegree[temp]))//入度为0, 则入栈Push(S, temp);}}if (count < ALG.vexnum)return -1;elsereturn 1;
}

AOE Graph

/* ---- AOE图 ---- */
int TopologicalOrder(ALGraph ALG, SqStack<int>& T, int eventEarly[]);int CriticalPath(ALGraph ALG);//并用栈T返回G的一个拓扑序列
int TopologicalOrder(ALGraph ALG, SqStack<int>& T, int eventEarly[])
{int indegree[MAX_VERTEX_NUM] = {0};FindInDegree(ALG, indegree);//求各顶点入度//初始化for (int i = 0; i < ALG.vexnum; i++)eventEarly[i] = 0;SqStack<int> S{};InitStack(S);for (int i = 0; i < ALG.vexnum; i++)if (!indegree[i])Push(S, i);//如果某个顶点的入度为0, 将其入栈int temp;int count = 0;int k;while (!StackEmpty(S)){Pop(S, k);Push(T, k);//将节点入栈//下面有一行代码用于输出序列//printf("顶点编号: %d 顶点字符: %c\n", k, ALG.vertices[k].data);++count;for (ArcNode* p = ALG.vertices[k].firstarc; p; p = p->nextarc){temp = p->adjvex;       //修改入度if (!(--indegree[temp]))//入度为0, 则入栈Push(S, temp);eventEarly[temp] = MAX(eventEarly[k] + p->weight, eventEarly[temp]);}}#if TEST//检验所求的eventEarly数组的值是否正确printf("检验所求的eventEarly数组的值是否正确: \n");for (int i = 0; i < ALG.vexnum; i++)std::cout << ALG.vertices[i].data << ' ' << eventEarly[i] << std::endl;
#endifif (count < ALG.vexnum)return -1;elsereturn 1;
}//找关键路径.
int CriticalPath(ALGraph ALG)
{/** @brief* 求事件vj(即节点 j )的最早发生时间eventEarly[j] \n* eventEarly(0) = 0 \n* eventEarly(j) = max{ eventEarly(i) + dut<i,j> }, i是j的前驱 \n* eventEarly的初始值全部为0 \n* */int eventEarly[MAX_VERTEX_NUM] = {0};/** @brief* 求事件vj(即节点 j)的最早发生时间eventLast[j] \n* eventLast[n-1] = eventEarly[n-1] \n* eventLast(j) = min{ eventLast(k) - dut<j, k> }, k是j的后继 \n* eventLast的初始值全部为对应的eventEarly \n* */int eventLast[MAX_VERTEX_NUM] = {0};for (int i = 0; i < MAX_VERTEX_NUM; i++)eventEarly[i] = 0;SqStack<int> T{};TopologicalOrder(ALG, T, eventEarly);//寻找出度为0的节点, 其即为AOE的汇点, 并将其eventLast赋值为 对应的eventEarlyint outdegree[MAX_VERTEX_NUM];for (int i = 0; i < ALG.vexnum; i++)outdegree[i] = 0;FindOutDegree(ALG, outdegree);int end;for (int i = 0; i < ALG.vexnum; i++)if (outdegree[i] == 0){end = i;break;}for (int i = 0; i < MAX_VERTEX_NUM; i++)eventLast[i] = INF;eventLast[end] = eventEarly[end];//计算eventLast[]int j;int k;ArcNode* p;Pop(T, j);//将end弹出来while (!StackEmpty(T)){Pop(T, j);for (p = ALG.vertices[j].firstarc; p; p = p->nextarc){k = p->adjvex;eventLast[j] = MIN(eventLast[j], eventLast[k] - p->weight);}}#if TEST//检验所求的eventLast数组和eventEarly数组是否正确printf("\n");printf("检查: eventLast 和 eventEarly\n");for (int i = 0; i < ALG.vexnum; i++)printf("%c eventEarly: %d, eventLsat: %d\n", ALG.vertices[i].data, eventEarly[i], eventEarly[i]);
#endif/**@brief* (边)的edgeEarly, edgeLast \n* j -> k, 则这条边 \n* edgeEarly = eventEarly[j] \n* edgeLast = eventLsat[k] - dut<j, k> \n* */int dut;int edgeEarly, edgeLast;char tag;for (j = 0; j < ALG.vexnum; j++){for (p = ALG.vertices[j].firstarc; p; p = p->nextarc){k = p->adjvex, dut = p->weight;edgeEarly = eventEarly[j];edgeLast = eventLast[k] - dut;tag = (edgeEarly == edgeLast) ? '*' : ' ';printf("%c -> %c: weight: %d edgeEarly: %d, edgeLast: %d %c\n", ALG.vertices[j].data, ALG.vertices[k].data, dut, edgeEarly, edgeLast, tag);//std::cout << j << "->" << k << ' ' << dut << ' ' << edgeEarly << ' ' << edgeLast << ' ' << tag << std::endl;}}return 1;
}

Date Structure: Graph --- Represent graph structure with adjacency list相关推荐

  1. DAG-GNN: DAG Structure Learning with Graph Neural Networks

    文章目录 概 主要内容 代码 Yu Y., Chen J., Gao T. and Yu M. DAG-GNN: DAG structure learning with graph neural ne ...

  2. 【论文解读|AAAI2021】HGSL - Heterogeneous Graph Structure Learning for Graph Neural Networks 图神经网络的异构图结构学习

    文章目录 1 摘要 2 引言 相关工作 3 方法 3.1 特征图产生器 3.1.1 特征相似图 3.1.2特征传播图 3.2 语义图生成器 4 实验 5 结论 论文链接: http://shichua ...

  3. 【论文阅读-HGP-SL】Hierarchical Graph Pooling with Structure Learning

    论文地址:https://arxiv.org/pdf/1911.05954 代码地址:https://github.com/cszhangzhen/HGP-SL 这篇论文提出了一种新的基于TopK的图 ...

  4. 【2019/ICML】DAG-GNN: DAG Structure Learning with Graph Neural Networks

    原文链接:https://dreamhomes.github.io/posts/202101041501.html 文章链接:https://arxiv.org/abs/1904.10098 源码链接 ...

  5. Graph Neural Networks: A Review of Methods and Applications(图神经网络:方法与应用综述)

    Graph Neural Networks: A Review of Methods and Applications 图神经网络:方法与应用综述 Jie Zhou , Ganqu Cui , Zhe ...

  6. A Comprehensive Survey on Graph Neural Networks(图神经网络综合研究)

    A Comprehensive Survey on Graph Neural Networks 图神经网络综合研究 Zonghan Wu, Shirui Pan, Member, IEEE, Feng ...

  7. Paper:《Graph Neural Networks: A Review of Methods and Applications—图神经网络:方法与应用综述》翻译与解读

    Paper:<Graph Neural Networks: A Review of Methods and Applications-图神经网络:方法与应用综述>翻译与解读 目录 < ...

  8. 【论文阅读】A Gentle Introduction to Graph Neural Networks [图神经网络入门](7)

    [论文阅读]A Gentle Introduction to Graph Neural Networks [图神经网络入门](7) Into the Weeds Other types of grap ...

  9. paper reading:[renormalization]Semi-supervised Classification with Graph Convolutional Networks

    paper reading:[Renormalization Trick] Semi-supervised classification with graph convolutional networ ...

最新文章

  1. R语言ggplot2可视化:可视化堆叠的直方图、在bin中的每个分组部分添加数值标签、使用position_stack函数设置
  2. Form_Form与OAF页面互相调用(案例)
  3. 23. 进程并发控制之Semaphore
  4. wxWidgets:wxResourceTranslationsLoader类用法
  5. rip协议中周期性广播路由信息的报文_技术实操||距离矢量路由协议-RIP
  6. SPA 单页Web应用
  7. 关于StringIndexOutOfBoundsException那些事~
  8. “升级 iOS 最新系统后,我弃用了 iPhone!”
  9. loss函数之MultiLabelSoftMarginLoss
  10. 【LeetCode】【字符串】题号:*520. 检测大写字母
  11. 谈谈计算机专业职业技能,计算机专业职业技能论文
  12. IEEE的论文哪里可以下载?
  13. WIN10插上耳机还是声音外放
  14. 嵌入式C语音基础夯实备用实战
  15. 日语基础学习 Day 07
  16. [超光速与空间]超光速与预测
  17. Charles(Mac)抓取安卓手机app的包
  18. RV1126笔记二十三:Nginx及cgi移植
  19. python输入某年某月某日判断这是第几天_Python编程实现输入某年某月某日计算出这一天是该年第几天的方法...
  20. 手机电池为什么会爆炸?

热门文章

  1. 【愚公系列】2023年06月 网络安全(交通银行杯)-变异凯撒
  2. 自媒体人必备的4个素材网站,再也不用担心找不到素材
  3. AcWing 1695 果壳游戏
  4. 【机器学习】支持向量机中的核函数(理论+图解+公式推导)
  5. 关于ad hoc retrieval的解释
  6. 吃鸡be服务器位置,吃鸡BE服务器未连接正常是什么意思 | 手游网游页游攻略大全...
  7. requests 返回 521
  8. 企业连锁店用智能网关轻松进行异地组网
  9. JAVA面向对象详细
  10. 雅虎修复邮件服务大漏洞:研究者获10000美金奖励