0.忘差不多的基础知识
- typedef
- .与->
- 字符串输入与输出
靠一段代码整体回顾一下:
#include <stdio.h>
typedef struct NinePercent
{
char *name;
float practiceTime; // Two and a half year
int behavior; //sing&jump rap basketball
}Person;
void SetName(Person *man,char *myname){
man->name=myname;
}
int main(){
char myname[]="DZ"; // point to string array's first index
Person cxk;
Person man;
cxk.name="ikun";
cxk.practiceTime=2.5;
printf("Hello Everyone,My name is %s and I had practiced for %3.1f year\n",cxk.name, cxk.practiceTime);
SetName(&man,myname);
printf("my name is %s\n",man.name);
return 0;
}
由于可爱的小马珍珠不属于NinePercent,所以我们可以将NinePercent删除,程序仍是正确。
typedef struct 【NinePercent】//可以省略
{
char *name;
float practiceTime; // Two and a half year
int behavior; //sing&jump rap basketball
}Person;
1.正文
1.0 Init
(1)数据结构
- vexs[vexsNum] 好像没啥用
- arcs[vexsNum][VexsNum] 记录各点之间路径长度·
- vexsNum、arcsNum 自定义顶点数与边数
typedef struct{
int vexs[MaxVexNum];
int arcs[MaxArcsNum][MaxArcsNum];
int vexsNum;
int arcsNum;
}Graph;
(2)Dijkstra Needed
- distance数组 记录到v0最短路径长度
- path数组 记录前驱节点·
- final数组 标记状态,1表示已经找到最短路径
typedef int Patharc[MaxVexNum]; // 用于存储最短路径下标的数组
typedef int ShortPathTable[MaxVexNum]; // 用于存储到各点最短路径的
int final[MaxVexNum]
1.1. CreateGraph
S1:顶点数组
for 一下搞定
S2:边矩阵
- i==j arcs[i][j]=0
- 存在边的进行赋值,arcs[i][j]=arcs[j][i]
- 其余为INFINITY
1.2.ShortestPath_Dijkstra
S1:Init
(1)final 置0
(2)D[vi]=arcs[v0][vi]
(3)P[vi]= -1
(4)额外设置v0
(*D)[v0]=0;
//(*P)[i]=-1; 不去设置的原因是作为输出时候的判断标志
final[v0]=1;
S2:core loop 进行vexsNum次
(1)min{D[]}
遍历D[],确定min,并记录min的下标进行(3)的操作
for(j=0;j<G.vexsNum;j++){
//没确定且更小,则更新
if(!final[j]&&(*D)[j]<min){
min=(*D)[j];
temp=j;// 记住最小的下标
}
}
(2)final[vmin] 置1
(3)用D[min]松弛
//(3)对未确定最短路径的每个点进行松弛
for(j=0;j<G.vexsNum;j++){
if(!final[j] && (min+G.arcs[temp][j]<(*D)[j])){
(*D)[j]=min+G.arcs[temp][j];
(*P)[j]=temp;
1.3.printf
实现当前P[temp]的值为下一个路径的下标
NextIdex = P[temp];
temp =P[NextIdex];
loop,直到找到v0
//使用到P[v0]=-1
while(P[j]!=-1){
printf("%d ",P[j]);
j=P[j];
}
2.完整代码
#include <stdio.h>
#define MaxVexNum 20
#define MaxArcsNum 20
#define Graph_INFINITY 653300
// def path matrix
typedef struct{
int vexs[MaxVexNum];
int arcs[MaxArcsNum][MaxArcsNum];
int vexsNum;
int arcsNum;
}Graph;
typedef int Patharc[MaxVexNum]; // 用于存储最短路径下标的数组
typedef int ShortPathTable[MaxVexNum]; // 用于存储到各点最短路径的权值和
// func: 创建图
//结构体用点 (.),结构体指针用箭头 (->)
//因为要G要传出来用,所以用指针
void CreateGraph(Graph *G){
G->arcsNum=16;
G->vexsNum=9;
int i,j;
// 对顶点数组
for(i=0;i<G->vexsNum;i++){
G->vexs[i]=i;
}
// 对边矩阵
// 0. 对角线为0
// 1. 其余为Graph_INFINITY
for(i=0;i<G->vexsNum;i++){
for(j=0;j<G->vexsNum;j++){
if (i==j)
G->arcs[i][j]=0;
else{
G->arcs[i][j] = Graph_INFINITY;
G->arcs[j][i] = Graph_INFINITY;
}
}
}
// 2. 再对有的进行初始化,初始化后对称点也需要
G->arcs[0][1]=1;
G->arcs[0][2]=5;
G->arcs[1][2]=3;
G->arcs[1][3]=7;
G->arcs[1][4]=5;
G->arcs[2][4]=1;
G->arcs[2][5]=7;
G->arcs[3][4]=2;
G->arcs[3][6]=3;
G->arcs[4][5]=3;
G->arcs[4][6]=6;
G->arcs[4][7]=9;
G->arcs[5][7]=5;
G->arcs[6][7]=2;
G->arcs[6][8]=7;
G->arcs[7][8]=4;
for(i = 0; i < G->vexsNum; i++)
{
for(j = i; j < G->vexsNum; j++)
{
G->arcs[j][i] =G->arcs[i][j];
}
}
}
void ShortestPath_Dijkstra(Graph G,int v0,Patharc *P,ShortPathTable *D){
int i,j,temp,min;
int final[MaxVexNum];
// 0.init
//(1)final 0 (2)D arcs[v0][vi](3)P -1
for(i=0;i<G.vexsNum;i++){
final[i]=0;
(*D)[i]=G.arcs[v0][i];
(*P)[i]=-1;
}
//(4)额外设置v0
(*D)[v0]=0;
//(*P)[i]=-1; 不去设置的原因是作为输出时候的判断标志
final[v0]=1;
// 1.core loop 进行vexsNum次
for(i=0;i<G.vexsNum;i++){
//(1)min{P[]} (2)final[vmin] 置1 (3)用D[min]松弛
min=Graph_INFINITY;
//2.
for(j=0;j<G.vexsNum;j++){
//没确定且更小,则更新
if(!final[j]&&(*D)[j]<min){
min=(*D)[j];
temp=j;// 记住最小的下标
}
}
//(2)
final[temp]=1;
//(3)对未确定最短路径的每个点进行松弛
for(j=0;j<G.vexsNum;j++){
if(!final[j] && (min+G.arcs[temp][j]<(*D)[j])){
(*D)[j]=min+G.arcs[temp][j];
(*P)[j]=temp;
}
}
}
}
int main(){
int i,j,v0;
Patharc P; //记录前驱节点
ShortPathTable D; //某点到其余各点的最短路径
//0. init
Graph G;
v0=0; // 自己设置,可以加scanf
// printf("请输出顶点数与边数:(numOfvexs,numOfarcs)");
// scanf("%d,%d",&G.vexsNum,&G.arcsNum);
//1. creat graph
CreateGraph(&G);
//2. dijkstra
ShortestPath_Dijkstra(G, v0, &P, &D);// 返回的是P D数组,还要进行输出操作,所以传入指针
//3. print 对每个点
for(i=1;i<G.vexsNum;i++){
printf("v%d -v%d:",v0,i);
j=i;
//使用到P[v0]=-1
//发现还要一个变量来控制P的下标,不然i改变
while(P[j]!=-1){
printf("%d ",P[j]);
j=P[j];
}
printf("\n");
}
return 0;
}
文章评论