数据结构学习第十八天
Posted 57one
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构学习第十八天相关的知识,希望对你有一定的参考价值。
14:07:40 2019-09-02
学习
PTA第17题 六度空间理论
可以在结构体中 加上一个属性来表示层数
我是利用一个整型变量 Level和 一个数组LevelSize来记录每层数量多少
需要注意要处理 最远距离小于6的情况
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<malloc.h> 4 5 int NumberOfConnect[1001]; 6 typedef struct ENode* Edge; 7 struct ENode 8 9 int V1, V2; 10 ; 11 12 typedef struct Graph* MGraph; 13 struct Graph 14 15 int Nv; 16 int Ne; 17 int G[1001][1001]; 18 ; 19 20 MGraph CreateMGraph(int MaxVertex) 21 22 MGraph Graph; 23 Graph = (MGraph)malloc(sizeof(struct Graph)); 24 Graph->Nv = MaxVertex; 25 Graph->Ne = 0; 26 for (int i = 1; i <=Graph->Nv; i++) 27 for (int j = 1; j <=Graph->Nv; j++) 28 Graph->G[i][j] = 0; 29 return Graph; 30 31 void Insert(MGraph Graph,Edge E) 32 33 Graph->G[E->V1][E->V2] = 1; 34 Graph->G[E->V2][E->V1] = 1; 35 36 MGraph BuildGraph() 37 38 MGraph Graph; 39 Edge E; 40 int Nv; 41 scanf("%d", &Nv); 42 Graph = CreateMGraph(Nv); 43 scanf("%d\\n", &(Graph->Ne)); 44 for (int i = 0; i < Graph->Ne; i++) 45 46 E = (Edge)malloc(sizeof(struct ENode)); 47 scanf("%d %d\\n", &(E->V1), &(E->V2)); 48 Insert(Graph, E); 49 50 return Graph; 51 52 53 int IsEdge(MGraph Graph,int V, int W) 54 55 return (Graph->G[V][W] == 1) ? 1 : 0; 56 57 58 //利用广度优先搜索 59 #define Size 1001 60 int Queue[Size]; 61 int Front = 1; 62 int Rear = 0; 63 int size = 0; 64 int IsEmpty() 65 66 return (size == 0) ? 1 : 0; 67 68 int Succ(int Value) 69 70 if (Value < Size) 71 return Value; 72 else 73 return 0; 74 75 void EnQueue(int V) 76 77 Rear = Succ(Rear + 1); 78 Queue[Rear] = V; 79 size++; 80 81 int DeQueue() 82 83 int V = Queue[Front]; 84 Front = Succ(Front + 1); 85 size--; 86 return V; 87 88 void InitializeQueue() 89 90 for (int i = 0; i < Size; i++) 91 Queue[i] = 0; 92 Front = 1; 93 Rear = 0; 94 size = 0; 95 96 int visited[1001]; 97 void InitializeVisited() 98 99 for (int i = 0; i < 1001; i++) 100 visited[i] = 0; 101 102 int BFS(MGraph Graph, int V) 103 104 InitializeVisited(); 105 InitializeQueue(); 106 EnQueue(V); 107 visited[V] = 1; 108 int Level = 0; //从第0层开始 109 int LevelSize[1001] = 0; 110 LevelSize[Level] = 1; //第0层自己算一个元素 111 NumberOfConnect[V]++; //令该顶点可以访问的个数加1 112 while (!IsEmpty()) 113 114 int W = DeQueue(); 115 LevelSize[Level]--; 116 for (int i = 1; i <= Graph->Nv; i++) 117 if (!visited[i]&&IsEdge(Graph, W, i)) 118 119 LevelSize[Level+1]++; 120 EnQueue(i); 121 visited[i] = 1; 122 NumberOfConnect[V]++; 123 124 if (LevelSize[Level] == 0) 125 Level++; 126 if (Level==6) 127 return NumberOfConnect[V]; 128 129 //当 达不到6 层时 130 return NumberOfConnect[V]; 131 132 void OutPut(MGraph Graph,int V,float num) 133 134 printf("%d: %.2f%%\\n", V, (num / Graph->Nv) * 100); 135 136 void SDS(MGraph Graph) 137 138 for (int i = 1; i <= Graph->Nv; i++) 139 140 int num = BFS(Graph,i); 141 OutPut(Graph,i,num); 142 143 144 int main() 145 146 MGraph G; 147 G = BuildGraph(); 148 SDS(G); 149 return 0; 150
在网络中,求两个不同顶点之间的所有路径中 边的权值之和最小的那一条路径
这条路径就是两点之间的最短路径(Shortest Path)
第一个顶点为起点(源点 Source)
最后一个顶点为终点(Destination)
问题分类:
①单源最短路径问题:从某固定源点出发,求其到所有其他顶点的最短路径
Ⅰ.(有向/无向)无权图
Ⅱ.(有向/无向)有权图
②多源最短路径问题:求任意两顶点间的最短路径
无权图的单源最短路算法
按照递增(非递减)的顺序找出到各个项点的最短路 //利用 广度优先遍历
有权图的单源最短路算法
按照递增(非递减)的顺序找出到各个项点的最短路 //利用 Dijkstra算法
Dijkstra算法
令$S=\\left\\\\text源点s + 已经确定了最短路径的顶点 v_i \\right\\$
多源最短路算法
①直接将单源最短路算法调用$V$遍 //对于稀疏图效果好
②Floyd算法 //对于稠密图效果好
Floyd算法
$D^k[i][j]=路径\\left\\i \\rightarrow \\left\\l \\leq k \\right\\ \\rightarrow j \\right\\$ 的最小长度
$D^0,D^1,\\cdots,D^|V|-1[i][j] 即给出了i到j的真正最短距离$
三种算法:
1 //无权图的单源最短路算法 2 3 int Dist[50]; //S到W的最短距离(源点到某点的最短距离) 4 int Path[50]; //S到W的路上经过的某顶点 5 void InitializeDistAndPath() 6 7 for (int i = 0; i < 50; i++) 8 9 Dist[i] = -1; 10 Path[i] = -1; 11 12 13 void UnWeighted(MGraph Graph, Vertex S) 14 15 InitializeDistAndPath(); 16 EnQueue(S); 17 Dist[S] = 0; 18 while (!IsEmpty()) 19 20 Vertex V = DeQueue(); 21 for (int W = 0; W < Graph->Nv; W++) 22 if (Dist[W] == -1 && IsEdge(Graph, V, W)) 23 24 Dist[W] = Dist[V] + 1; 25 Path[W] = V; 26 EnQueue(W); 27 28 29 30 31 //有权图的单源最短路算法 32 //Dijkstra算法 //不能解决有负边的情况 33 int Dists[50]; 34 int Collected[50]; 35 int Paths[50]; 36 Vertex FindMinDist(MGraph Graph) //返回未被收录顶点中 Dists最小者 37 38 Vertex MinV, V; 39 int MinDist = INFINITY; 40 for (V = 0; V < Graph->Nv; V++) 41 42 if (Collected[V]!=0&&Dists[V] < MinDist) 43 44 MinDist = Dists[V]; 45 MinV = V; 46 47 48 if (MinDist < INFINITY) 49 return MinV; 50 else 51 return 0; 52 53 int Dijkstra(MGraph Graph, Vertex S) 54 55 Vertex V; 56 //初始化 57 for (int i = 0; i < Graph->Nv; i++) 58 59 Dists[i] = Graph->G[S][i]; //计算出与源点直接相连的节点的Dists 60 if (Dists[i] < INFINITY) 61 Paths[i] = S; 62 else 63 Paths[i] = -1; 64 65 66 Dists[S] = 0; //将源点收入 67 Collected[S] = 1; 68 69 while (1) 70 71 V = FindMinDist(Graph); 72 if (!V) 73 break; 74 Collected[V] = 1; //收录 75 for (Vertex W = 0; W < Graph->Nv; W++) 76 77 if (Collected[W] == 0 && IsEdge(Graph, V, W)) 78 79 if (Graph->G[V][W] < 0) //有负边 80 return -1; //不能解决 81 if (Dists[V] + Graph->G[V][W] < Dists[W]) 82 83 Dists[W] = Dists[V] + Graph->G[V][W]; 84 Paths[W] = V; 85 86 87 88 89 return 1; //算法执行完毕 90 91 92 //多源最短路算法 93 //Floyd算法 94 int D[50][50]; 95 int Pa[50][50]; //计算最短路径 96 int Floyd(MGraph Graph) 97 98 for (int i = 0; i < Graph->Nv; i++) 99 for (int j = 0; j < Graph->Nv; j++) 100 101 D[i][j] = Graph->G[i][j]; 102 Pa[i][j] = -1; 103 104 105 for (int k = 0; k < Graph->Nv; k++) 106 for (int i = 0; i < Graph->Nv; i++) 107 for (int j = 0; j < Graph->Nv; j++) 108 if (D[i][k] + D[k][j] < D[i][j]) 109 110 D[i][j] = D[i][k] + D[k][j]; 111 if (i == j && D[i][j] < 0) 112 return -1; //有负值圈 解决失败 113 Pa[i][j] = k; 114 115
以上是关于数据结构学习第十八天的主要内容,如果未能解决你的问题,请参考以下文章