图
1.学习总结
1.1图的思维导图

1.2 图结构学习体会
图(graph):是一种较线性表和树更为复杂的数据结构,图形结构中,结点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关 
线性表:数据元素之间仅有线性关系,每个数据元素只有一个直接前驱和一个直接后继 
树:树形结构中,数据元素之间有着明显的层次关系,并且每一层上的数据元素可能和下一层中多个元素(即其孩子结点)相关,但只能和上一层中一个元素(即其双亲结点)相关
- 深度遍历算法:将一个子节点的所有内容全部遍历完后再遍历其他节点
 - 广度遍历算法:分层次进行遍历
 - Prim和Kruscal算法:在加权连通图里搜索最小生成树,代码量较少
 - Dijkstra算法:以起始点为中心向外扩展直到扩展到终点为止,最后得到一个最短路径
 - 拓扑排序算法:有向图,不唯一,必须判断有无环路
 
2.PTA实验作业
题目1: 图着色问题
1.设计思路
用图的遍历解题,遍历的时候判断颜色是否相同即可。 
便利过程中应注意需要不同颜色的个数等于k。
2.代码截图

 
3. PTA提交列表说明

题目2.公路村村通
1.设计思路
求最小生成树的问题,给出城镇和城镇之间的费用作为权重,求出要连通所有城镇的最少费用,也就是求出这个图的最小生成树,当然不能连通时输出-1
是先用邻接矩阵的方法存储图,然后就运用Prim算法求出这个图的最小生成树,最后输出最少费用dist
2.代码截图




3.pta提交列表

3.题目:城市间紧急救援
1.设计思路
基于dijkstra算法的问题。 要考虑最优路径上的点权和尽可能大,所以出现两路径长度相等时要进行关于点权和的判断。
另外还要记录最短路径的条数,只需开一个数组记载,每次更新时基于上一点的最短路径条数更新即可。每次更新最优路径时,将上一点记录在theway数组,用于最后输出最优路径。
2.代码截图

 


3.pta提交列表

3.截图本周题目集的PTA最后排名

4. 阅读代码
7-3 六度空间
- #include<stdio.h>
 - #include<malloc.h>
 - #define MAX 10001//最大顶点数
 - /**
 - *解题思想:
 - *对图进行广度搜索
 - *得出每层中的顶点数
 - *计算百分比
 - */
 - int BFS(int i, int N, int ** snap)
 - {// 队列 遍历登记 队头 队尾 计数器 层数
 - int q[MAX], visit[MAX], front, rear, count, level, last, tail, v, j;
 - for (j = 0; j < 10001; j++)//初始化数组
 - visit[j] = 0;
 - visit[i] = 1;//开始结点
 - front = rear = -1;//队列初始化
 - count = 1;//计算六度空间的个数
 - level = 0;//level计算层数,等于6时跳出
 - last = i;//last为上一层最后的顶点
 - q[++rear] = i;//入队 当前顶点所在层数
 - while (front<rear) //遍历队列(六层以内)
 - {
 - /*
 - *图的广度搜索原理解析:
 - *类似二叉树的层序遍历
 - *1、从所需要的顶点进入图(类似利用此顶点为树的根结点,构建一棵树)
 - *2、根结点入队列
 - *3、寻找与此顶点相连的所有顶点并放入队列中(图的临接矩阵中,储存的是每个顶点间的边的关系,而且无向图的临接矩阵一定为对称矩阵)
 - *4、当顶点所在行遍历结束,取出队列的下一个顶点,重复。直至遍历所有的顶点
 - */
 - v = q[++front]; //出队
 - for (j = 1; j <= N; j++)//遍历
 - if (!visit[j] && snap[v][j] == 1)
 - {//当结点没有记录而且此处结点为顶点时
 - q[++rear] = j;//入队列
 - visit[j] = 1;//记录对应位置
 - count++;//计数器
 - tail = j;//tail是当前层的最后一个顶点
 - }
 - if (v == last)
 - {
 - level++;//层数加一
 - last = tail;//记录最后一个顶点
 - }
 - if (6 == level)//等于六层时,退出循环
 - break;
 - }
 - return count;//返回六度空间内所有顶点数
 - }
 - int main(void)
 - {
 - int N, M;
 - int count = 0;
 - scanf("%d %d", &N, &M);
 - int **snap;//实现动态分配二维数组
 - /*注意:
 - *******动态分配必须按照顺序分配
 - *******同时数组释放内存的时候要按照先后顺序释放
 - *******否则会出现野指针
 - *******内存泄漏导致程序崩溃
 - */
 - snap = (int**)malloc(sizeof(int*) * (N + 1));
 - if (snap == NULL)
 - return -1;
 - //动态分配内存存在失败的可能,所以
 - //在进行动态分配内存后
 - //应该进行对应的指针是否为空指针的判断
 - int i, x, y, j;
 - for (i = 0; i <= N; i++)
 - {
 - *(snap + i) = (int *)malloc(sizeof(int) * (N + 1));
 - if (*(snap + i) == NULL)
 - return -1;
 - }
 - for (i = 0; i < M; i++)
 - {
 - scanf("%d %d", &x, &y);//无向图对角线对称
 - snap[x][y] = snap[y][x] = 1;//关系对等
 - }
 - for (i = 1; i <= N; i++)
 - {
 - count = BFS(i, N, snap);
 - printf("%d: %.2f%%\n", i, (float)count / N * 100);
 - }
 - //直接进行头指针的内存释放不全等于所有指针内存的释放
 - //free(snap);
 - for (i = 0; i < N; i++)
 - {
 - free(*(snap + i));
 - *(snap + i) = NULL;
 - }
 - free(snap);
 - snap = NULL;
 - return 0;
 - }
 
                    
                
                
            
        
浙公网安备 33010602011771号