前言:数据结构一般就四种关系:集合、线性、树、图。这篇文章打算对图这类数据结构做一个概览。先介绍图的一些术语(复制粘贴:));然后讲解一下图的各种存储形式;最后把图的应用记录一下,具体应用算法放在算法分类里面。

一、图的一些术语

image.png
image.png
image.png

二、图存储

邻接矩阵

:::info 创建无向网 :::

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define MVNum 100
  4. #define MaxInt 32767
  5. typedef char VerTexType;
  6. typedef int ArcType;
  7. /**
  8. * 邻接矩阵存储形式
  9. */
  10. typedef struct {
  11. /* data */
  12. VerTexType vexs[MVNum]; //顶点表
  13. ArcType arcs[MVNum][MVNum]; //邻接矩阵
  14. int vexnum, arcnum; //图的当前顶点和边数
  15. }AMGraph;
  16. /**
  17. * 确定v在G中的位置,即顶点数组的下标
  18. */
  19. int LocateVex(AMGraph &G, char v) {
  20. for (int i = 0; i < G.vexnum;i++) {
  21. if (v == G.vexs[i]){
  22. return i;
  23. }
  24. }
  25. }
  26. /**
  27. * 创建无向网
  28. * 如果创建无向图
  29. */
  30. void CreateUDN(AMGraph &G) {
  31. // 采用邻接矩阵表示法,创建无向图G
  32. cout << "请输入顶点数和边数:" << endl;
  33. cin >> G.vexnum >> G.arcnum; //输入顶点数和边数
  34. // 初始化顶点
  35. for (int i = 0; i < G.vexnum;i++){
  36. cout << "请输入第" << i << "个顶点值" << endl;
  37. cin >> G.vexs[i];
  38. }
  39. // 初始化邻接矩阵的边的权值为最大值
  40. for (int i = 0; i < G.vexnum;i++) {
  41. for (int j = 0; j < G.vexnum;j++) {
  42. G.arcs[i][j] = MaxInt;
  43. }
  44. }
  45. // 构造邻接矩阵
  46. for (int k = 0; k < G.arcnum;k++) {
  47. cout << "请输入每条边所依附的顶点和权值:" << endl;
  48. char v1, v2;
  49. int w; //一条边所依附的顶点和权值
  50. cin >> v1 >> v2 >> w;
  51. int i = LocateVex(G, v1);
  52. int j = LocateVex(G, v2);
  53. G.arcs[i][j] = w;
  54. G.arcs[j][i] = w;
  55. }
  56. }
  57. void Display(AMGraph &G) {
  58. for (int i = 0; i < G.vexnum;i++) {
  59. for (int j = 0; j < G.vexnum;j++) {
  60. cout << G.arcs[i][j] << " ";
  61. }
  62. cout << endl;
  63. }
  64. }
  65. int main() {
  66. AMGraph test;
  67. // CreateUDN(test);
  68. Display(test);
  69. }

:::tips 创建无向图 ::: 对CreateUDN 进行处理:

  • G.arcs[i][j] = MaxInt;改为G.arcs[i][j] = 0;
  • 将w改为常量1即可

:::tips 创建有向网 ::: 对CreateUDN 进行处理:

  • 删除G.arcs[j][i] = w;

:::tips 创建有向图 ::: 对CreateUDN 进行处理:

  • 删除G.arcs[j][i] = w;

    邻接表

    ```cpp

    include

    using namespace std;

define MVNum 100

define MaxInt 32767

typedef char VerTexType; typedef int OtherInfo;

/**

  • 邻接表存储 */

/**

  • 存储结构 / typedef struct ArcNode { //边结点
    int adjvex; //该边所指向的结点的位置 struct ArcNode
    nextarc; //指向下一条边的指针 OtherInfo info; //和边相关的其他信息 }ArcNode;

typedef struct VNode { //顶点信息 VerTexType data; //数据域,存放顶点vi的名称或其他有关信息 ArcNode *firstarc; //指向第一条依附该顶点的边的指针 }VNode, AdjList[MVNum]; //AdjList表示邻接表的类型

typedef struct { AdjList vertices; int vexnum, arcnum; //图当前的顶点数和边数 }ALGragh; //邻接表(Adjacency List)

/**

  • 找到v顶点在图中的位置 */ int LocateVex(ALGragh &G, char v) { for (int i = 0; i < G.vexnum;i++) {
    1. if (v == G.vertices[i].data) {
    2. return i;
    3. }
    } }

/**

  • 邻接表创建无向图 */ void CreateUDG(ALGragh &G) { cin >> G.vexnum >> G.arcnum; // 邻接表的顶点数和边数 for (int i = 0; i < G.vexnum;i++) {

    1. cin >> G.vertices[i].data;
    2. G.vertices[i].firstarc = NULL;

    }

    for (int k = 0; k < G.arcnum;k++) {

    1. char v1, v2;
    2. cin >> v1 >> v2;
    3. int i = LocateVex(G, v1);
    4. int j = LocateVex(G, v2);
    5. ArcNode *p1 = new ArcNode;
    6. p1->adjvex = j;
    7. p1->nextarc = G.vertices[i].firstarc;
    8. G.vertices[i].firstarc = p1;
    9. ArcNode *p2 = new ArcNode;
    10. p2->adjvex = i;
    11. p2->nextarc = G.vertices[j].firstarc;
    12. G.vertices[j].firstarc = p1;

    } } ```

    有向图:十字链表存储

    ```cpp

    include

    using namespace std; typedef int Status;

    define OK 1;

//——有向图的十字链表储存表示——

define MAX_VERTEX_NUM 20

typedef char VerTexType; typedef int InfoType; typedef struct ArcBox { int tailvex, headvex; //该弧的头尾和头顶点的位置 struct ArcBox hlink, tlink; //分别为弧头相同和弧尾相同的链域 InfoType *info; //该弧相关信息的指针 }ArcBox;

typedef struct VexNode { VerTexType data; ArcBox firstin, firstout; //分别指向该顶点的第一项入弧和出弧 }VexNode;

typedef struct { VexNode xlist[MAX_VERTEX_NUM]; //表头向量 int vexnum, arcnum; //有向图的当前顶点数和弧数 }OLGraph; //十字链表(Orthogonal List)

  1. <a name="vsryl"></a>
  2. ### 无向图:邻接多重表存储
  3. ```cpp
  4. #include <bits/stdc++.h>
  5. using namespace std;
  6. typedef int Status;
  7. #define OK 1;
  8. //----无向图的邻接多重表储存表示----
  9. #define MAX_VERTEX_NUM 20
  10. typedef char VerTexType;
  11. typedef int InfoType;
  12. typedef enum
  13. {
  14. unvisited, visited //枚举unvisited是0,visited是1,注意没有分号
  15. }VisitIf;
  16. typedef struct EBox
  17. {
  18. VisitIf mark; //访问标记
  19. int ivex, jvex; //该边依附的两个顶点的位置
  20. struct EBox *ilink, *jlink; //分别指向依附这两个顶点的下一条边
  21. InfoType *info; //该边的信息指针
  22. }EBox;
  23. typedef struct VexBox
  24. {
  25. VerTexType data;
  26. EBox *firstedge; //指向第一条依附该顶点的边
  27. }VexBox;
  28. typedef struct
  29. {
  30. VexBox adjmulist[MAX_VERTEX_NUM];
  31. int vexnum, arcnum; //无向图当前的顶点数和边数
  32. }AMLGraph; //邻接多重表(Adjacency Multilist)

其他:边集数组

其他:链式前向星

三、图的应用

  • 最小生成树
  • 最短路径
  • 环路
  • 关键路径

具体这几类问题都是算法中的贪心算法所属,故将其放到算法分类里面了。