最短路径(难)

news2025/1/30 16:08:31

目录

一、Dijkstra算法

动态演示: 

 关键代码:

 完整代码:

运行结果: 

 二、Floyd算法

详细介绍 

 关键算法:

完整代码:

运行结果:


 

一、Dijkstra算法

  • Dijkstra算法:可以求带权图中一个顶点到其余各顶点的最短路径(单源最短路径) 
  • 基本算法步骤:
    第一步:初始时,顶点集S只含源点,即S=\left \{ \left. v \right \} \right.,顶点v到自己的距离为0.顶点集U包含除v外其他顶点,源点vU中顶点i的距离为边上权值。
    第二步:从U中选取一个顶点u,它是源点vU中距离最小的一个顶点,然后把顶点u加入S
    第三步:以顶点u作为新考虑的中间点,修改U中那些从顶点uj有边的顶点j的最短路径长度
    U中其他顶点从顶点u没有边到达的顶点不需要调整)。考虑顶点u的时候,从源点v到顶点jj属于U)有如下两条路径,在这两条路径中取更短的路径,求从源点v到顶点j的最短路径长度=min(C_{vj},C_{vu}+W_{uj})    ,其中:
      1.不经过顶点u的路径,路径长度为C_{vj}
      2.从顶点u有一条边到达顶点j的路径,该路径由两段构成,其长度为C_{vu}+W_{uj}
    第四步:重复步骤二和步骤三,直到所有顶点都包含在S中。
  • 算法设计:
    S数组表示集合S中的元素,即对于顶点j,S[j]=1表示它在S中,S[j]=0表示它在U
    dist[j]保存从源点v到顶点j的当前最短路径长度,它的初值为<v,j>边上权值
    path[j]保存从源点vj的最短路径,实际上path[j]保存从源点v到顶点j的当前最短路径中顶点j的前一个顶点编号
  • 动态演示: 

 

  •  关键代码:

void Dijkstra(MGraph G, int v)
{
	int S[MAXV];//用于记录顶点是否在集合U中
	int dist[MAXV];//用于保存从源点到某顶点的当前最短路径长度
	int path[MAXV];//用于保存从源点到某顶点的最短路径
	for (int i = 0; i < G.n; i++)//初始化
	{
		S[i] = 0;
	}
	S[v] = 1;
	for (int i = 0; i < G.n; i++)
	{
		dist[i] = G.edges[v][i];
	}
	for (int j = 0; j < G.n; j++)//path[]数组初始化
	{
		if (S[j]==0&&G.edges[v][j] != INF && G.edges[v][j] != 0)//当v到i没有边的时候
		{
			path[j] = v;
		}
		else
		{
			path[j] = -1;
		}
	}
	
	int u = 0;
	for (int i = 0; i < G.n-1; i++)//循环向S中添加n-1个顶点
	{
		int min = INF;
		for (int k = 0; k < G.n; k++)//选取不在S中并且具有最小距离的顶点
		{
			if (S[k] == 0 && dist[k] < min)
			{
				min = dist[k];
				u = k;
			}
		}
		S[u] = 1;
		for (int i = 0; i < G.n; i++)
		{
			if (S[i] == 0)//仅仅调整不属于S中的顶点的最短路径长度,且需要考虑新加入S中的顶点
			{
				if (G.edges[u][i] + dist[u] < dist[i] && G.edges[u][i] != INF)
				{
					dist[i] = G.edges[u][i] + dist[u];
					path[i] = u;
				}
			}
		}
	}
	Disp(G, S, dist, path, v);
}
void Disp(MGraph G, int S[], int dist[], int path[],int v)
{
	for (int i = 0; i < G.n; i++)
	{
		if (S[i] == 1 && i != v)
		{
			cout << "从" << G.vexs[v] << "到" << G.vexs[i] << "最短路径长度为:" << dist[i]<<endl;
		}
		if (S[i] == 1 && i != v)
		{
			int d[MAXV]={0};
			int m = 0;
			d[m] = i;//先存放路径上的终点
			int k = path[i];
			if (path[i] == -1)
			{
				cout << "无路径!" << endl;
			}
			else
			{
				while (k != v)
				{
					m++;
					d[m] = k;
					k = path[k];
				}
				m++;
				d[m] = v;//添加路径上的起点
				cout << d[m];//先输出起点
				for (int j = m-1 ; j >= 0; j--)
				{
					cout << "->" << d[j];
				}
				cout << endl;
			}
			
		}
	}
}
  •  完整代码:

//Dijk.h
#pragma once
#include<iostream>
#include<stdio.h>
using namespace std;

#define MAXV 100
#define INF 10000
typedef int EdgeType;
typedef char VertexType;
typedef struct
{
	int n, e;
	EdgeType edges[MAXV][MAXV];
	VertexType vexs[MAXV];
}MGraph;
void Creat(MGraph& G,int A[][MAXV],int n);//创建图的邻接矩阵
void Print(MGraph G);//打印
void Dijkstra(MGraph G, int v);//从v出发到各个顶点的最短路径
void Disp(MGraph G, int S[], int dist[], int path[],int v);//输出路径
void Dijkstra2(MGraph G, int v, int w);//从v出发到u的最短路径
void DispPath(MGraph G, int S[], int dist[], int path[], int v,int u);//输出从v到u的最短路径
//Dijks.cpp
#include"Dijk.h"
void Creat(MGraph& G, int A[][MAXV], int n)
{
	G.n = n;
	G.e = 0;
	cout << "请依次输入顶点信息:";
	for (int i = 0; i < n; i++)
	{
		cin >> G.vexs[i];
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			G.edges[i][j] = A[i][j];
			if (A[i][j] != 0 && A[i][j] != INF)
			{
				G.e++;
			}
		}
	}
}

void Print(MGraph G)
{
	for (int i = 0; i < G.n; i++)
	{
		for (int j = 0; j < G.n; j++)
		{
			cout << G.edges[i][j] << " ";
		}
		cout << endl;
	}
}

void Dijkstra(MGraph G, int v)
{
	int S[MAXV];//用于记录顶点是否在集合U中
	int dist[MAXV];//用于保存从源点到某顶点的当前最短路径长度
	int path[MAXV];//用于保存从源点到某顶点的最短路径
	for (int i = 0; i < G.n; i++)//初始化
	{
		S[i] = 0;
	}
	S[v] = 1;
	for (int i = 0; i < G.n; i++)
	{
		dist[i] = G.edges[v][i];
	}
	for (int j = 0; j < G.n; j++)//path[]数组初始化
	{
		if (S[j]==0&&G.edges[v][j] != INF && G.edges[v][j] != 0)//当v到i没有边的时候
		{
			path[j] = v;
		}
		else
		{
			path[j] = -1;
		}
	}
	
	int u = 0;
	for (int i = 0; i < G.n-1; i++)//循环向S中添加n-1个顶点
	{
		int min = INF;
		for (int k = 0; k < G.n; k++)//选取不在S中并且具有最小距离的顶点
		{
			if (S[k] == 0 && dist[k] < min)
			{
				min = dist[k];
				u = k;
			}
		}
		S[u] = 1;
		for (int i = 0; i < G.n; i++)
		{
			if (S[i] == 0)//仅仅调整不属于S中的顶点的最短路径长度,且需要考虑新加入S中的顶点
			{
				if (G.edges[u][i] + dist[u] < dist[i] && G.edges[u][i] != INF)
				{
					dist[i] = G.edges[u][i] + dist[u];
					path[i] = u;
				}
			}
		}
	}
	Disp(G, S, dist, path, v);
}

void Disp(MGraph G, int S[], int dist[], int path[],int v)
{
	for (int i = 0; i < G.n; i++)
	{
		if (S[i] == 1 && i != v)
		{
			cout << "从" << G.vexs[v] << "到" << G.vexs[i] << "最短路径长度为:" << dist[i]<<endl;
		}
		if (S[i] == 1 && i != v)
		{
			int d[MAXV]={0};
			int m = 0;
			d[m] = i;//先存放路径上的终点
			int k = path[i];
			if (path[i] == -1)
			{
				cout << "无路径!" << endl;
			}
			else
			{
				while (k != v)
				{
					m++;
					d[m] = k;
					k = path[k];
				}
				m++;
				d[m] = v;//添加路径上的起点
				cout << d[m];//先输出起点
				for (int j = m-1 ; j >= 0; j--)
				{
					cout << "->" << d[j];
				}
				cout << endl;
			}
			
		}
	}
}
void Dijkstra2(MGraph G, int v, int w)//从v出发到w的最短路径
{
	int S[MAXV];
	int dist[MAXV];
	int path[MAXV];
	for (int i = 0; i < G.n; i++)//初始化S[MAXV]数组
	{
		S[i] = 0;
	}
	S[v] = 1;
	for (int i = 0; i < G.n; i++)//初始化dist[MAXV]数组
	{
		dist[i] = G.edges[v][i];
	}
	for (int i = 0; i < G.n-1; i++)//初始化path[MAXV]数组
	{
		if (G.edges[v][i] != INF && G.edges[v][i] != 0)
		{
			path[i] = v;
		}
		else
		{
			path[i] = -1;
		}
	}

	int k = 0;
	for (int i = 0; i < G.n-1; i++)//循环向S中添加n-1个顶点
	{
		int min = INF;
		for (int j = 0; j < G.n; j++)//选取不在S中并且具有最小距离的顶点
		{
			if (S[j] == 0 && G.edges[v][j] != 0 && dist[j] < min)
			{
				min = dist[j];
				k = j;
			}
		}
		S[k] = 1;
		if (k == w)//如果新加入集合S的顶点恰好是要找的终点,就退出循环
		{
			break;
		}
		else
		{
			for (int j = 0; j < G.n; j++)
			{
				if (S[j] == 0)//更新不属于U中的顶点的最短路径长度
				{
					if (G.edges[v][j] != 0 && G.edges[k][j] + dist[k] < dist[j])
					{
						dist[j] = G.edges[k][j] + dist[k];
						path[j] = k;
					}
				}
			}
		}
		
	}
	DispPath(G, S, dist, path, v, w);
}
void DispPath(MGraph G, int S[], int dist[], int path[], int v, int w)//输出从v到w的最短路径
{
	if (S[w] == 1 && w != v)
	{
		cout << "从" << G.vexs[v] << "到" << G.vexs[w] << "最短路径长度为:" << dist[w] << endl;
	}
	if (S[w] == 1 && w != v)
	{
		int d[MAXV];
		int m = 0;
		d[m] = w;
		int k = path[w];
		while (k != v)
		{
			m++;
			d[m] = k;
			k = path[k];
		}
		m++;
		d[m] = v;
		cout << "最短路径是:" << d[m];
		for (int j = m - 1; j >= 0; j--)
		{
			cout << "->" << d[j];
		}
	}
}
//Text.cpp
#include"Dijk.h"
int main()
{
	int A[][MAXV] = { {0,4,6,6,INF,INF,INF},{INF,0,1,INF,7,INF,INF},{INF,INF,0,INF,6,4,INF},{INF,INF,2,0,INF,5,INF},{INF,INF,INF,INF,0,INF,6},{INF,INF,INF,INF,1,0,8},{INF,INF,INF,INF,INF,INF,0} };
	MGraph G;
	Creat(G, A, 7);
	cout << "图的邻接矩阵:" << endl;
	Print(G);
	Dijkstra(G, 0);
	cout << endl;
	Dijkstra2(G, 2, 6);
	return 0;
}
  • 运行结果: 

 二、Floyd算法

  • 详细介绍 

 

 

 

  •  关键算法:

void Floyd(MGraph G)//Floyd算法
{
	int A[MAXV][MAXV];//保存最短路径长度
	int path[MAXV][MAXV];//保存最短路径
	for (int i = 0; i < G.n; i++)//初始化A[][]数组
	{
		for (int j = 0; j < G.n; j++)
		{
			A[i][j] = G.edges[i][j];
		}
	}
	for (int i = 0; i < G.n; i++)//初始化path[][]数组
	{
		for (int j = 0; j < G.n; j++)
		{
			if (G.edges[i][j] == INF || G.edges[i][j] == 0)//i到j不存在边
			{
				path[i][j] = -1;
			}
			else
			{
				path[i][j] = i;//i到j存在边的时候,下标为j的顶点前驱顶点的编号是i
			}
		}
	}
	for (int k = 0; k < G.n; k++)//依次将下标从0到G.n的顶点作为中转点
	{
		for (int i = 0; i < G.n; i++)
		{
			for (int j = 0; j < G.n; j++)
			{
				if ((A[i][k] + A[k][j]) < A[i][j])//找到更短路径长度
				{
					A[i][j] = A[i][k] + A[k][j];//修改路径长度
					path[i][j] = path[k][j];//修改下标为j的顶点的前驱顶点
 //而path[k][j]存放的是恰好是从下标为k到下标为j顶点的路径中,下标为j的顶点的前驱顶点编号
				}
			}
		}
	}
	DisPath(G, A, path);
	/*for (int i = 0; i < G.n; i++)
	{
		for (int j = 0; j < G.n; j++)
		{
			cout << path[i][j] << " ";
		}
		cout << endl;
	}
	for (int i = 0; i < G.n; i++)
	{
		for (int j = 0; j < G.n; j++)
		{
			cout << A[i][j] << " ";
		}
		cout << endl;
	}*/
}
void DisPath(MGraph G, int A[][MAXV], int path[][MAXV])
{
	for (int i = 0; i < G.n; i++)
	{
		for (int j = 0; j < G.n; j++)
		{
			if (A[i][j] != 0 && A[i][j] != INF && i != j)
			{
				cout << "从" << G.vexs[i] << "到" << G.vexs[j] << "最短路径长度是:" << A[i][j] << endl;
				int d[MAXV];
				int m = 0;
				d[m] = j;//先存终点的下标
				int k = path[i][j];
				while (k != i && k != -1)
				{
					m++;
					d[m] = k;
					k = path[i][k];
				}
				m++;
				d[m] = i;//存起点的下标
				cout << "路径是:" << d[m];
				for (int p = m - 1; p >= 0; p--)
				{
					cout << "->" << d[p];
				}
				cout << endl;
			}
		}
	}
}
  • 完整代码:

//Floyd.h
#pragma once
#include<iostream>
#include<stdio.h>
using namespace std;

#define MAXV 100
#define INF 10000
typedef int VertexType;
typedef int EdgeType;
typedef struct
{
	int n, e;
	VertexType vexs[MAXV];
	EdgeType edges[MAXV][MAXV];
}MGraph;
void Creat(MGraph &G, int E[][MAXV], int n);//创建邻接矩阵
void Print(MGraph G);//打印图
void Floyd(MGraph G);//Floyd算法
void DisPath(MGraph G, int A[][MAXV], int path[][MAXV]);//打印最短路径
//Floyd.cpp
#include"Floyd.h"
void Creat(MGraph &G, int E[][MAXV], int n)
{
	G.n = n;
	G.e = 0;
	cout << "请依次输入顶点:";
	for (int i = 0; i < G.n; i++)
	{
		cin >> G.vexs[i];
	}
	for (int i = 0; i < G.n; i++)
	{
		for (int j = 0; j < G.n; j++)
		{
			G.edges[i][j] = E[i][j];
			if (E[i][j] != 0 && E[i][j] != INF)
			{
				G.e++;
			}
		}
	}
}
void Print(MGraph G)
{
	for (int i = 0; i < G.n; i++)
	{
		for (int j = 0; j < G.n; j++)
		{
			cout << G.edges[i][j] << " ";
		}
		cout << endl;
	}
}

void Floyd(MGraph G)//Floyd算法
{
	int A[MAXV][MAXV];//保存最短路径长度
	int path[MAXV][MAXV];//保存最短路径
	for (int i = 0; i < G.n; i++)//初始化A[][]数组
	{
		for (int j = 0; j < G.n; j++)
		{
			A[i][j] = G.edges[i][j];
		}
	}
	for (int i = 0; i < G.n; i++)//初始化path[][]数组
	{
		for (int j = 0; j < G.n; j++)
		{
			if (G.edges[i][j] == INF || G.edges[i][j] == 0)//i到j不存在边
			{
				path[i][j] = -1;
			}
			else
			{
				path[i][j] = i;//i到j存在边的时候,下标为j的顶点前驱顶点的编号是i
			}
		}
	}
	for (int k = 0; k < G.n; k++)//依次将下标从0到G.n的顶点作为中转点
	{
		for (int i = 0; i < G.n; i++)
		{
			for (int j = 0; j < G.n; j++)
			{
				if ((A[i][k] + A[k][j]) < A[i][j])//找到更短路径长度
				{
					A[i][j] = A[i][k] + A[k][j];//修改路径长度
					path[i][j] = path[k][j];//修改下标为j的顶点的前驱顶点
 //而path[k][j]存放的是恰好是从下标为k到下标为j顶点的路径中,下标为j的顶点的前驱顶点编号
				}
			}
		}
	}
	DisPath(G, A, path);
	/*for (int i = 0; i < G.n; i++)
	{
		for (int j = 0; j < G.n; j++)
		{
			cout << path[i][j] << " ";
		}
		cout << endl;
	}
	for (int i = 0; i < G.n; i++)
	{
		for (int j = 0; j < G.n; j++)
		{
			cout << A[i][j] << " ";
		}
		cout << endl;
	}*/
}


void DisPath(MGraph G, int A[][MAXV], int path[][MAXV])
{
	for (int i = 0; i < G.n; i++)
	{
		for (int j = 0; j < G.n; j++)
		{
			if (A[i][j] != 0 && A[i][j] != INF && i != j)
			{
				cout << "从" << G.vexs[i] << "到" << G.vexs[j] << "最短路径长度是:" << A[i][j] << endl;
				int d[MAXV];
				int m = 0;
				d[m] = j;//先存终点的下标
				int k = path[i][j];
				while (k != i && k != -1)
				{
					m++;
					d[m] = k;
					k = path[i][k];
				}
				m++;
				d[m] = i;//存起点的下标
				cout << "路径是:" << d[m];
				for (int p = m - 1; p >= 0; p--)
				{
					cout << "->" << d[p];
				}
				cout << endl;
			}
		}
	}
}
//Text.cpp
#include"Floyd.h"
int main()
{
	int M[][MAXV] = { {0,5,INF,7},{INF,0,4,2},{3,3,0,2},{INF,INF,1,0} };
	MGraph G;
	Creat(G, M, 4);
	cout << "图的邻接矩阵:" << endl;
	Print(G);
	cout << endl;
	Floyd(G);
	return 0;
}
  • 运行结果:

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/104842.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开发者还能这样开发小游戏变现

根据《2022微信小游戏增长白皮书》显示&#xff0c;目前微信小游戏开发者数量已经超过10万人次&#xff0c;特别是在持续出现小游戏爆火社交平台的趋势下&#xff0c;小游戏发展势头强劲。 此外仅看微信小游戏的商业规模&#xff0c;2022年相较于2021年实现了超 30%的商业增长…

快速了解Azure SQL部署类型的小技巧

目录 &#xff08;一&#xff09;前言 &#xff08;二&#xff09;正文 1. 语法 2. 结果分析 3. 实例 &#xff08;1&#xff09;SQL SERVER &#xff08;2&#xff09;Azure SQL &#xff08;一&#xff09;前言 我们知道在常规的SQL SERVER中我们会使用SELECT VERSIO…

我国汽车保险杠行业对汽车产业依存度较大 市场需求呈良性上升态势

根据观研报告网发布的《2022年中国汽车保险杠市场分析报告-市场发展格局与投资潜力研究》显示&#xff0c;汽车保险杠是汽车车身上一种较大的外覆盖零部件&#xff0c;其作用是在汽车发生碰撞时&#xff0c;保护汽车车身及附件&#xff0c;轻微碰撞可以依靠保险杠自身吸收能量&…

MySQL中的这14个神仙功能,惊艳到我了!!!

前言 我最近几年用MYSQL数据库挺多的&#xff0c;发现了一些非常有用的小玩意&#xff0c;今天拿出来分享到大家&#xff0c;希望对你会有所帮助。 1.group_concat 在我们平常的工作中&#xff0c;使用group by进行分组的场景&#xff0c;是非常多的。 比如想统计出用户表中…

劲牌连续两年问鼎全国质量大奖背后的密码

11月24日&#xff0c;第二十届全国质量奖“中国杰出质量人”正式公布&#xff0c;劲牌公司董事长吴少勋成为全国10人名单之一。这是劲牌公司继2021年获得第十九届全国质量奖组织奖后&#xff0c;又获得全国质量奖个人奖。连续两年分别获得全国质量奖组织奖和个人奖&#xff0c;…

18岁开始学习编程是否来得及?

18岁开始学习编程完全来得及&#xff0c;不仅来得及&#xff0c;而且还可以选择走专业的程序研发路线&#xff0c;在当前产业互联网的推动下&#xff0c;未来程序开发岗位的数量还会进一步得到攀升。 18岁开始学习编程可以根据自身的实际情况来规划具体的学习路线&#xff0c;对…

java回顾:ssm整合、纯注解开发

目录 一、搭建环境 1.1、spring环境搭建 1.1.1 测试SpringIOC环境 1.2、搭建Mybatis环境(原生mybatis) 二、Spring整合mybatis 三、Spring整合SpringMVC 四、SSM执行流程 五、纯注解开发配置文件模板 声明&#xff1a; SpringMVC: 注解 XML 注解: Control…

[streamlit]数据科学科研工作者的神器,必须要推荐一下

1. 前言 做科研当然要有过硬的专业知识&#xff0c;但是也少不了一些辅助&#xff0c;才能最大程度发挥我们的能力。因此&#xff0c;除去我们模型性能优秀&#xff0c;结果良好以外&#xff0c;如何进行一个好的展示&#xff0c;也是非常有必要的。那么今天&#xff0c;我们就…

推荐系统:基于ConvNCF推荐算法的推荐系统实现 代码+数据详细教程

1.案例知识点 推荐系统任务描述:通过用户的历史行为(比如浏览记录、购买记录等等)准确的预测出用户未来的行为;好的推荐系统不仅如此,而且能够拓展用户的视野,帮助他们发现可能感兴趣的却不容易发现的item;同时将埋没在长尾中的好商品推荐给可能感兴趣的用户。ConvNCF推…

西瓜书-决策树

决策树 决策树划分时&#xff0c;当前属性集为空&#xff0c;或所有样本在所有属性上取值相同&#xff0c;将结点标记为叶节点&#xff0c;其类别标记为当前样本集中样本数最多的类。 决策树算法的核心在于&#xff1a;选择最优划分属性 判别分类的三种情形&#xff1a; 当前…

[前端攻坚]:详解call、apply、bind的实现

call apply bind 的实现的面试中几乎必定出现的一些内容&#xff0c;今天来用一篇文章整理一下这里的内容&#xff0c;加深一下JS基础知识体系。同时文章也被收录到我的《JS基础》专栏中&#xff0c;欢迎大家点击收藏加关注。 call的实现 call() 方法使用一个指定的 this 值和单…

Oracle Ask Tom分区学习系列: 面向开发者的分区(Partitioning)教程

Oracle Partitioning: A Step-by-Step Introduction for Developers是Oracle数据库开发者课程之一。 Development with Oracle Partitioning/使用 Oracle 分区进行开发 Partitioning in the database reflects the same way we handle large tasks in the real world. When a t…

Redis分布式锁的10个坑

前言 大家好&#xff0c;我是田螺。 日常开发中&#xff0c;经常会碰到秒杀抢购等业务。为了避免并发请求造成的库存超卖等问题&#xff0c;我们一般会用到Redis分布式锁。但是使用Redis分布式锁&#xff0c;很容易踩坑哦~ 本文田螺哥将给大家分析阐述&#xff0c;Redis分布式…

如何优化 MySQL 服务器

有一些数据库服务器的优化技术&#xff0c;主要是管理系统配置而不是调整 SQL 语句。它适用于那些希望确保服务器的性能以及可伸缩性的 DBA&#xff0c;以及适用于启动安装脚本建立数据库和运行 MySQL 自己进行开发、测试等以提生产力的开发人员。 系统因素 一些系统级方面也会…

推荐几个方法教你学会怎样制作视频剪辑

随着时代的发展&#xff0c;新媒体行业的壮大&#xff0c;应该不少小伙伴每天都需要制作视频剪辑吧&#xff0c;有些可能是因为从事短视频行业&#xff0c;每天就需要发送视频内容&#xff0c;才能吸引观众&#xff0c;也有些可能只是想单纯分享一些生活视频。那你知道如何制作…

List接口-ArrayList、LinkedList和Vector

1.List 接口和常用方法 1.1List 接口基本介绍 import java.util.ArrayList; import java.util.List;public class List_ {SuppressWarnings({"all"})public static void main(String[] args) {//1. List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复 [案例]…

Linux网络编程之socket通信

Linux网络编程之socket通信 一、socket相关函数使用 1.1 IP地址转换函数&#xff1a; 小端法&#xff1a;&#xff08;pc本地存储&#xff09; 高位存高地址&#xff0c;低位存低地址。 大端法&#xff1a;&#xff08;网络存储&#xff09; 高位存低地址&#xff0c;低位存…

13基于多目标粒子群算法的微电网优化调度(matlab程序)

参考文献 基于多目标粒子群算法的微电网优化调度——王金全&#xff08;2014电网与清洁能源&#xff09; 主要内容 针对光伏电池、风机、微型燃气轮机、柴油发电机以及蓄电池组成的微电网系统的优化问题进行研究&#xff0c;在满足系统约束条件下&#xff0c;建立了包含运行…

day25【代码随想录】左叶子之和、找树左下角的值、从中序与后序遍历序列构造二叉树、从中序与前序遍历序列构造二叉树、最大二叉树

文章目录前言一、左叶子之和&#xff08;力扣404&#xff09;1、递归遍历2、非递归遍历二、找树左下角的值&#xff08;力扣513&#xff09;1、迭代法&#xff08;层序遍历&#xff09;2、递归法三、从中序与后序遍历序列构造二叉树&#xff08;力扣106&#xff09;四、从中序与…

微服务框架 SpringCloud微服务架构 微服务面试篇 54 微服务篇 54.1 SpringCloud常见组件有哪些?

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 微服务面试篇 文章目录微服务框架微服务面试篇54 微服务篇54.1 SpringCloud常见组件有哪些&#xff1f;54 微服务篇 54.1 SpringCloud常见组…