数据结构之图

有幸掌握浅薄知识,不吝分享,保持独立思考,自主学习,共同进步。另求关注,点赞,评论,感谢!(tips:主页有数据结构全部知识点,以及知识点讲解,建立完善的数据结构知识体)

核心算法思想

图是由顶点集合以及顶点间的关系集合组成的一种数据结构。Graph = (V,E) V是顶点的又穷非空集合;E是顶点之间关系的有穷集合,也叫边集合。
有向图:顶点对<x,y>是有序的;无向图:顶点对<x,y>是无序的。


图有两种遍历算法:

深度优先遍历(Depth_First_Search),也称为深度优先搜索,简称DFS。

广度优先遍历(Breadth_First_Search),又称为广度优先搜索,简称BFS。

详细:遍历算法
算法实现不再举例,之后会出BFS和DFS的详细例题

实践出真知,代码案例

按照上面的有向图,编写一个程序,完成如下功能:
(1) 建立如下有向图G1的邻接矩阵输出,并由邻接矩阵产生邻接表输出之;
(2) 输出图G1从顶点0开始的深度优先遍历序列;
(3) 输出图G1从顶点0开始的广度优先遍历序列;
(4) 用普里姆算法输出从顶点0出发的最小生成树;

案例源码

#include <stdio.h>
#include <malloc.h>typedef int InfoType;
#define MAXV 100                //最大顶点个数
#define INF 32767               //INF表示∞
//以下定义邻接矩阵类型
typedef struct
{int no;                        //顶点编号InfoType info;                //顶点其他信息
} VertexType;                   //顶点类型
typedef struct                  //图的定义
{int edges[MAXV][MAXV];         //邻接矩阵int n, e;                     //顶点数,边数VertexType vexs[MAXV];       //存放顶点信息
} MGraph;                       //图的邻接矩阵类型
//以下定义邻接表类型
typedef struct ANode            //边的节点结构类型
{int adjvex;                //该边的终点位置struct ANode *nextarc;         //指向下一条边的指针InfoType info;               //该边的相关信息,这里用于存放权值
} ArcNode;
typedef int Vertex;
typedef struct Vnode            //邻接表头节点的类型
{Vertex data;               //顶点信息ArcNode *firstarc;            //指向第一条边
} VNode;
typedef VNode AdjList[MAXV];    //AdjList是邻接表类型
typedef struct
{AdjList adjlist;           //邻接表int n, e;                  //图中顶点数n和边数e
} ALGraph;                      //图的邻接表类型//-------------------------------------
//--------带权图的算法-----------------
//-------------------------------------
void MatToList1(MGraph g, ALGraph *&G)
//将邻接矩阵g转换成邻接表G
{int i, j;ArcNode *p; //表结点结构类型G = (ALGraph *)malloc(sizeof(ALGraph));for (i = 0; i<g.n; i++)                    //给邻接表中所有头节点的指针域置初值G->adjlist[i].firstarc = NULL;for (i = 0; i<g.n; i++)                  //检查邻接矩阵中每个元素for (j = g.n - 1; j >= 0; j--)if (g.edges[i][j] != 0 && g.edges[i][j] != INF)   //存在一条边{p = (ArcNode *)malloc(sizeof(ArcNode));    //创建一个节点*pp->adjvex = j;     //终点信息 p->info = g.edges[i][j];   //权值信息 p->nextarc = G->adjlist[i].firstarc;       //将*p链到链表后G->adjlist[i].firstarc = p;}G->n = g.n; G->e = g.e;
}void DispMat1(MGraph g)
//输出邻接矩阵g
{int i, j;for (i = 0; i<g.n; i++){for (j = 0; j<g.n; j++)if (g.edges[i][j] == INF)printf("%3s", "∞");elseprintf("%3d", g.edges[i][j]);printf("\n");}
}
void DispAdj1(ALGraph *G)
//输出邻接表G
{int i;ArcNode *p;for (i = 0; i<G->n; i++){p = G->adjlist[i].firstarc;printf("%3d: ", i);while (p != NULL){printf("%3d(%d)", p->adjvex, p->info);p = p->nextarc;}printf("\n");}
}int visited[MAXV] = { 0 };  //全局数组void DFS(ALGraph *G, int v)   //深度优先递归算法
{ArcNode *p;visited[v] = 1;                    //置已访问标记printf("%3d", v);                     //输出被访问顶点的编号p = G->adjlist[v].firstarc;             //p指向顶点v的第一条弧的弧头结点while (p != NULL){if (visited[p->adjvex] == 0)      //若p->adjvex顶点未访问,递归访问它DFS(G, p->adjvex);p = p->nextarc;                      //p指向顶点v的下一条弧的弧头结点}
}void BFS(ALGraph *G, int v)  //广度优先遍历
{ArcNode *p;int queue[MAXV], front = 0, rear = 0;         //定义循环队列并初始化int visited[MAXV];                      //定义存放结点的访问标志的数组int w, i;for (i = 0; i<G->n; i++) visited[i] = 0;     //访问标志数组初始化printf("%3d", v);                      //输出被访问顶点的编号visited[v] = 1;                            //置已访问标记rear = (rear + 1) % MAXV;queue[rear] = v;                            //v进队while (front != rear)                     //若队列不空时循环{front = (front + 1) % MAXV;w = queue[front];                      //出队并赋给wp = G->adjlist[w].firstarc;             //找与顶点w邻接的第一个顶点while (p != NULL){if (visited[p->adjvex] == 0)         //若当前邻接顶点未被访问{printf("%3d", p->adjvex);    //访问相邻顶点visited[p->adjvex] = 1;     //置该顶点已被访问的标志rear = (rear + 1) % MAXV;            //该顶点进队queue[rear] = p->adjvex;}p = p->nextarc;                     //找下一个邻接顶点}}printf("\n");
}
void Prim(MGraph g, int v)    //prim 算法求最小生成树
{int lowcost[MAXV], min, n = g.n;int closest[MAXV], i, j, k;/***初始化lowcost数组,closest数组(即从起点开始设置lowcost数组,closest数组相应的值,以便后续生成使用)***/for (i = 0; i < g.n; i++)//赋初值,即将closest数组都赋为第一个结点v,lowcost数组赋为第一个结点v到各结点的权重{closest[i] = v;lowcost[i] = g.edges[v][i];//g.edges[v][i]的值指的是结点v到i节点的权重}/**********************************开始生成其他的结点*********************************/for (i = 1; i < g.n; i++)//接下来找剩下的n-1个结点(g.n是图的节点个数){/*****找到一个结点,该节点到已选节点中的某一个结点的权值是当前最小的*****/min = INF;//INF表示正无穷(每查找一个结点,min都会重新更新为INF,以便获取当前最小权重的结点)for (j = 0; j < g.n; j++)//遍历所有结点{if (lowcost[j] != 0 && lowcost[j] < min)//若该结点还未被选且权值小于之前遍历所得到的最小值{min = lowcost[j];//更新min的值k = j;//记录当前最小权重的结点的编号}}/****************输出被连接结点与连接结点,以及它们的权值***************/printf("边(%d,%d)权为:%d\n", closest[k], k, min);/***********更新lowcost数组,closest数组,以便生成下一个结点************/lowcost[k] = 0;//表明k结点已被选了(作标记)//选中一个结点完成连接之后,作数组相应的调整for (j = 0; j < g.n; j++)//遍历所有结点{/* if语句条件的说明:* (1)g.edges[k][j] != 0是指k!=j,即跳过自身的结点* (2)g.edges[k][j]是指刚被选的结点k到结点j的权重,lowcost[j]是指之前遍历的所有结点与j结点的最小权重。若g.edges[k][j] < lowcost[j],则说明当前刚被选的结点k与节点j之间存在更小的权重,则需要更新*/if (g.edges[k][j] != 0 && g.edges[k][j] < lowcost[j]){//更新lowcost数组,closest数组lowcost[j] = g.edges[k][j];//更新权重,使其当前最小closest[j] = k;//进入到该if语句里,说明刚选的结点k与当前结点j有更小的权重,则closest[j]的被连接结点需作修改为k}}}}int main()
{ALGraph *G;//图的邻接表 MGraph g;//图的邻接矩阵 int path[MAXV], i, j, v = 0;//路径数组 g.n = 6; g.e = 10;//顶点的个数和边的个数 int A[MAXV][6] = {{ 0, 5, INF, 7, INF, INF },{ INF, 0, 4, INF, INF, INF },{ 8, INF, 0, INF, INF, 9 },{ INF, INF, 5, 0, INF, 6 },{ INF, INF, INF, 5, 0, INF },{ 3, INF, INF, INF, 1, 0 } };//邻接矩阵 for (i = 0; i<g.n; i++)for (j = 0; j<g.n; j++)g.edges[i][j] = A[i][j];//矩阵的赋值,A矩阵赋给g矩阵 printf("有向图G的邻接矩阵:\n");//文字,无意义 DispMat1(g);//输出矩阵 G = (ALGraph *)malloc(sizeof(ALGraph));MatToList1(g, G);//矩阵转换成链表 printf("图G的邻接表:\n"); DispAdj1(G);  //输出邻接表//G = (ALGraph *)malloc(sizeof(ALGraph));printf("从顶点0开始的DFS(递归算法):\n");DFS(G, 0); printf("\n");printf("从顶点0开始的BFS(非递归算法):\n");BFS(G, 0); printf("\n");printf("普里姆算法求解结果:\n");Prim(g, 0);return 0;
}

大一新生必看,自学必看,里昂详解数据结构之图相关推荐

  1. 大一新生必看,自学必看,里昂详解数据结构之二叉树

    数据结构之二叉树 有幸掌握浅薄知识,不吝分享,保持独立思考,自主学习,共同进步.另求关注,点赞,评论,感谢!(tips:主页有数据结构全部知识点,以及知识点讲解,建立完善的数据结构知识体) 核心算法思 ...

  2. 大一新生必看,自学必看,里昂详解数据结构之队列

    数据结构之队列 有幸掌握浅薄知识,不吝分享,保持独立思考,自主学习,共同进步.另求关注,点赞,评论,感谢!(tips:主页有数据结构全部知识点,以及知识点讲解,建立完善的数据结构知识体) 核心算法思想 ...

  3. 大一新生必看,自学必看,里昂详解数据结构之链表

    数据结构之链表 有幸掌握浅薄知识,不吝分享,保持独立思考,自主学习,共同进步.另求关注,点赞,评论,感谢!(tips:主页有数据结构全部知识点,以及知识点讲解,建立完善的数据结构知识体) 核心算法思想 ...

  4. 大一新生必看,自学必看,里昂详解数据结构之线性表

    数据结构之线性表(顺序表) 有幸掌握浅薄知识,不吝分享,保持独立思考,自主学习,共同进步.另求关注,点赞,评论,感谢!(tips:主页有数据结构全部知识点,以及知识点讲解,建立完善的数据结构知识体) ...

  5. 大一新生必看,自学必看,里昂详解数据结构之堆栈

    数据结构之堆栈 有幸掌握浅薄知识,不吝分享,保持独立思考,自主学习,共同进步.另求关注,点赞,评论,感谢!(tips:主页有数据结构全部知识点,以及知识点讲解,建立完善的数据结构知识体) 核心算法思想 ...

  6. 大一新生上手题(题目加源代码详解)(每日一题,一题多解)

    2019 数列有序! Problem Description 有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序.n从键盘输 ...

  7. 思科ccna认证工程师必看路由协议IGRP和EIGRP详解

    思科ccna认证工程师必看路由协议IGRP和EIGRP详解单单从他们的名字当中,我们就能猜到他们之间有很多的关联. IGRP: 一种内部网关路由协议,它由Cisco公司八十年代中期设计.使用组合用户配 ...

  8. 一看就懂的CE-NET详解

    一看就懂的CE-NET详解 针对问题 u-net及其变体存在限制,连续的pooling和交错的卷积运算会导致一些空间信息的丢失. 文章贡献 提出了一个DAC模块和一个RMP模块来捕获更多的高级特征并保 ...

  9. 计算机bios设置论文,玩转电脑必看知识——各种BIOS设置详解 的更多相关文章

    7.IDE Primary Master UDMA(第一个IDE主控制器下的UDMA模式) 8.IDE Primary Slave UDMA(第一个IDE从控制器下的UDMA模式) 9.IDE Sec ...

最新文章

  1. android定时循环,Android AlarmManager实现定时循环后台任务
  2. C++公历农历转换2020-2080年/除夕修正
  3. UML结构建模图———复合结构图
  4. 2020牛客国庆集训派对day1 ------ ABB(马拉车裸题 + 条件判断)
  5. 广义表的概念及其存储结构
  6. 【PR】调整音频的声音从大到小
  7. 2020.7.7 ETH价格分析
  8. cad放大_cad快捷键+鼠标操作,全了!
  9. 蓝牙人员定位追踪系统解决方案,蓝牙定位技术应用全面-新导智能
  10. 自动控制原理-频率特性 G(jw ) 定义
  11. 应用ceph文件系统存储(ceph-13.2.10)
  12. 【gcc】centos安装gcc
  13. c语言破解rar5文件,RAR5 文件格式解析
  14. 美图秀秀想让妹纸留下来分享美图,社交梦能如愿以偿吗?
  15. iMAG(爱码哥)新建应用
  16. 从园所“招生”和“提价”的需求切入,「掌通家园」要从工具转型成为平台...
  17. 学编程c语言高考能加分吗,学好编程,中高考都能加分,还能保送清华北大!...
  18. oracle增量恢复dg备库,rman增量恢复DG备库出现GAP的情况
  19. 蓝桥杯python组——平行四边形面积
  20. ❤ 就这?TypeScript其实并不难!(建议收藏)❤

热门文章

  1. R语言-来自Prosper的贷款数据探索
  2. 托福高频真词List10 // 附托福TPO阅读真题
  3. 单利模式的优缺点和使用场景
  4. 专门打游戏的手机精选:rog3散热好 续航好 玩游戏更好!
  5. ESP32-C3 应用 篇(实例二、通过蓝牙将传感器数据发送给手机,手机端控制 SK6812 LED)
  6. 支持GB28281协议的远程抓拍4G低功耗摄像头解决方案
  7. char和数值的类型转换
  8. Oracle的 wm_concat 的排序问题,Oracle的 listagg 函数
  9. 这可能是我用过最好用的SQL工具,免费还免安装,良心推荐SQL Studio
  10. ZSG-AP5甲烷传感器校验仪