数据结构学习第十八天

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 }
View Code

 

在网络中,求两个不同顶点之间的所有路径中 边的权值之和最小的那一条路径

这条路径就是两点之间的最短路径(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 }
View Code

 

posted @ 2019-09-03 01:51  57one  阅读(156)  评论(0编辑  收藏  举报