急死我了机试之Dijkstra

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;
	
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周树皮不皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值