【算法设计与分析】— —单源最短路径的贪心算法

news2024/9/23 21:19:47

🎃欢迎大家前去观看我的算法设计与分析专栏: 算法设计与分析_IT闫的博客-CSDN博客 希望对大家有所帮助!


🎃个人专栏:

🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客

🐳Java基础:Java基础_IT闫的博客-CSDN博客

🐋c语言:c语言_IT闫的博客-CSDN博客

🐟MySQL:数据结构_IT闫的博客-CSDN博客

🐠数据结构:​​​​​​数据结构_IT闫的博客-CSDN博客

💎C++:C++_IT闫的博客-CSDN博客

🥽C51单片机:C51单片机(STC89C516)_IT闫的博客-CSDN博客

💻基于HTML5的网页设计及应用:基于HTML5的网页设计及应用_IT闫的博客-CSDN博客​​​​​​

🥏python:python_IT闫的博客-CSDN博客

欢迎收看,希望对大家有用!

目录

🎯目的:

🎯内容:

 🎯代码(Java):

🎯运行结果:

🎯 算法分析:

🎯其他程序语言的实现:

🎐C语言程序:

🎐python程序:

🎐C++程序:


🎯目的:

1)了解贪心算法思想及基本原理;

2)掌握使用贪心算法求解问题的一般特征;

3)能够针对实际问题,能够正确选择贪心策略;

4)能够针对选择的贪心策略,证明算法的正确性;

5)能够根据贪心策略,正确编写代码;

6)能够正确分析算法的时间复杂度和空间复杂度。

🎯内容:

单源最短路径的贪心算法。

测试数据可选用下图,1为源点:

 🎯代码(Java):

package one;

public class Three {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int x1[][] = { { 0, 2, 0, 1, 0, 3, 0, 0 }, { 0, 0, 6, 0, 5, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 6 },
				{ 0, 10, 0, 0, 0, 0, 2, 0 }, { 0, 0, 9, 0, 0, 0, 0, 4 }, { 0, 0, 0, 5, 0, 0, 4, 0 },
				{ 0, 7, 0, 0, 3, 0, 0, 8 }, { 0, 0, 0, 0, 0, 0, 0, 0 } };
		int s = 1;// 表示原点
		int[] dist = new int[x1.length];// 表示原点到各点的最短距离
		boolean[] visited = new boolean[x1.length];
		int [] pre=new int[x1.length];//记录最短路径的前驱结点
		for (int i = 0; i < x1.length; i++) {// 初始化
			dist[i] = Integer.MAX_VALUE;// 初始化为无穷大
			visited[i] = false;// 初始化为没有被访问过
			pre[i]=-1;//前去初始化为-1
		}
		dist[s - 1] = 0;// 自身到自身为0

		// 找原点到各个顶点的距离
		for (int i = 0; i < x1.length; i++) {
			int mindist = Integer.MAX_VALUE;// 最短路径
			int mindistindex = -1;// 最短路径的索引
			// 寻找路径中最短的
			for (int j = 0; j < x1.length; j++) {
				if (!(visited[j]) && dist[j] < mindist) {
					// 更新数据
					mindist = dist[j];
					mindistindex = j;
				}
			}
			visited[mindistindex] = true;// 将顶点添加到已访问数组中
			// 更新最短距离
			for (int j = 0; j < x1.length; j++) {
				if (!visited[j] && x1[mindistindex][j] != 0 && dist[mindistindex] != Integer.MAX_VALUE
						&& dist[mindistindex] + x1[mindistindex][j] < dist[j]) {
					dist[j] = dist[mindistindex] + x1[mindistindex][j];// 更新最短距离
					pre[j]=mindistindex+1;//记录前驱结点
				}
			}
		}
		System.out.printf("顶点:  ");
		for (int i = 0; i < x1.length; i++) {
			System.out.printf((i+1)+"   ");
		}
		System.out.println();
		System.out.printf("距离:       ");
		for (int i = 1; i < x1.length; i++) {
			System.out.printf(dist[i]+"   ");
		}
		System.out.println();
		System.out.printf("前驱:       ");
		for (int i = 1; i < x1.length; i++) {
			System.out.printf(pre[i]+"   ");
		}
	}

🎯运行结果:

🎯 算法分析:

时间复杂度:

  • 初始化阶段:需要遍历所有的顶点,时间复杂度为O(n)。
  • 最短路径查找阶段:需进行n次迭代,每次迭代需要遍历所有顶点,时间复杂度为O(n^2),因此,总体时间复杂度为O(n^2)。

空间复杂度:

  • 使用了四个数组,其中x1占用了O(n^2)的空间,dist,visited,pre占用各自O(n)的空间。因此,空间复杂度为O(n^2)。

        需要注意的是,时间复杂度和空间复杂度的分析是基于给定图的规模为n的情况下。在实际应用中,如果图的规模非常大,可以考虑采用优化算法或数据结构来减小时间和空间的开销。

🎯其他程序语言的实现:

以下代码均有ai生成,读者如发现bug可以发在评论区,咱们一起解决❤️!

🎐C语言程序:

#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define SIZE 8 // 矩阵大小

void dijkstra(int graph[SIZE][SIZE], int source) {
    int dist[SIZE];     // 原点到各点的最短距离
    bool visited[SIZE]; // 记录节点是否被访问
    int pre[SIZE];      // 记录最短路径的前驱结点

    for (int i = 0; i < SIZE; i++) {
        dist[i] = INT_MAX;      // 初始化为无穷大
        visited[i] = false;     // 初始化为没有被访问过
        pre[i] = -1;            // 前驱初始化为-1
    }

    dist[source - 1] = 0; // 自身到自身为0

    // 找原点到各个顶点的距离
    for (int i = 0; i < SIZE; i++) {
        int minDist = INT_MAX; // 最短路径
        int minDistIndex = -1; // 最短路径的索引

        // 寻找路径中最短的
        for (int j = 0; j < SIZE; j++) {
            if (!visited[j] && dist[j] < minDist) {
                minDist = dist[j];
                minDistIndex = j;
            }
        }

        visited[minDistIndex] = true; // 将顶点添加到已访问数组中

        // 更新最短距离
        for (int j = 0; j < SIZE; j++) {
            if (!visited[j] && graph[minDistIndex][j] != 0 && dist[minDistIndex] != INT_MAX &&
                dist[minDistIndex] + graph[minDistIndex][j] < dist[j]) {
                dist[j] = dist[minDistIndex] + graph[minDistIndex][j]; // 更新最短距离
                pre[j] = minDistIndex + 1; // 记录前驱结点
            }
        }
    }

    printf("顶点:  ");
    for (int i = 0; i < SIZE; i++) {
        printf("%d   ", i + 1);
    }
    printf("\n");

    printf("距离:       ");
    for (int i = 1; i < SIZE; i++) {
        printf("%d   ", dist[i]);
    }
    printf("\n");

    printf("前驱:       ");
    for (int i = 1; i < SIZE; i++) {
        printf("%d   ", pre[i]);
    }
}

int main() {
    int graph[SIZE][SIZE] = {
        {0, 2, 0, 1, 0, 3, 0, 0},
        {0, 0, 6, 0, 5, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 6},
        {0, 10, 0, 0, 0, 0, 2, 0},
        {0, 0, 9, 0, 0, 0, 0, 4},
        {0, 0, 0, 5, 0, 0, 4, 0},
        {0, 7, 0, 0, 3, 0, 0, 8},
        {0, 0, 0, 0, 0, 0, 0, 0}
    };

    int source = 1; // 表示原点
    dijkstra(graph, source);

    return 0;
}

🎐python程序:

import sys

def dijkstra(x1, s):
    dist = [sys.maxsize] * len(x1) # 表示原点到各点的最短距离
    visited = [False] * len(x1)
    pre = [-1] * len(x1) # 记录最短路径的前驱结点
    dist[s - 1] = 0 # 自身到自身为0

    for _ in range(len(x1)):
        mindist = sys.maxsize # 最短路径
        mindistindex = -1 # 最短路径的索引
        # 寻找路径中最短的
        for j in range(len(x1)):
            if not visited[j] and dist[j] < mindist:
                # 更新数据
                mindist = dist[j]
                mindistindex = j
        visited[mindistindex] = True # 将顶点添加到已访问数组中
        # 更新最短距离
        for j in range(len(x1)):
            if not visited[j] and x1[mindistindex][j] != 0 and dist[mindistindex] != sys.maxsize and dist[mindistindex] + x1[mindistindex][j] < dist[j]:
                dist[j] = dist[mindistindex] + x1[mindistindex][j] # 更新最短距离
                pre[j] = mindistindex + 1 # 记录前驱结点

    print("顶点:", end=" ")
    for i in range(len(x1)):
        print(i + 1, end=" ")
    print()
    
    print("距离:", end="    ")
    for i in range(1, len(x1)):
        print(dist[i], end=" ")
    print()
    
    print("前驱:", end="    ")
    for i in range(1, len(x1)):
        print(pre[i], end=" ")
    print()

if __name__ == "__main__":
    x1 = [[0, 2, 0, 1, 0, 3, 0, 0],
          [0, 0, 6, 0, 5, 0, 0, 0],
          [0, 0, 0, 0, 0, 0, 0, 6],
          [0, 10, 0, 0, 0, 0, 2, 0],
          [0, 0, 9, 0, 0, 0, 0, 4],
          [0, 0, 0, 5, 0, 0, 4, 0],
          [0, 7, 0, 0, 3, 0, 0, 8],
          [0, 0, 0, 0, 0, 0, 0, 0]]
    s = 1 # 表示原点
    dijkstra(x1, s)

        请注意,Python中没有类似Java中的整型溢出问题,因此使用了sys.maxsize作为无穷大。另外,Python的索引是从0开始的,所以在输出时顶点和索引都需要加1。希望对你有所帮助!如有其他问题,请随时问我。

🎐C++程序:

#include<iostream>
using namespace std;

int main(){
    int x1[8][8]={{0,2,0,1,0,3,0,0},
                   {0,0,6,0,5,0,0,0},
                   {0,0,0,0,0,0,0,6},
                   {0,10,0,0,0,0,2,0},
                   {0,0,9,0,0,0,0,4},
                   {0,0,0,5,0,0,4,0},
                   {0,7,0,0,3,0,0,8},
                   {0,0,0,0,0,0,0,0}};
    int s=1;
    const int n=8;
    int dist[n],pre[n];
    bool visited[n];
    for(int i=0;i<n;i++){
        dist[i]=INT_MAX;
        visited[i]=false;
        pre[i]=-1;
    }
    dist[s-1]=0;
    for(int i=0;i<n;i++){
        int mindist=INT_MAX,mindistindex=-1;
        for(int j=0;j<n;j++){
            if(!visited[j]&&dist[j]<mindist){
                mindist=dist[j];
                mindistindex=j;
            }
        }
        visited[mindistindex]=true;
        for(int j=0;j<n;j++){
            if(!visited[j]&&x1[mindistindex][j]!=0&&dist[mindistindex]!=INT_MAX&&dist[mindistindex]+x1[mindistindex][j]<dist[j]){
                dist[j]=dist[mindistindex]+x1[mindistindex][j];
                pre[j]=mindistindex+1;
            }
        }
    }
    cout<<"顶点:  ";
    for(int i=0;i<n;i++){
        cout<<i+1<<"   ";
    }
    cout<<endl;
    cout<<"距离:       ";
    for(int i=1;i<n;i++){
        cout<<dist[i]<<"   ";
    }
    cout<<endl;
    cout<<"前驱:       ";
    for(int i=1;i<n;i++){
        cout<<pre[i]<<"   ";
    }
    cout<<endl;
    return 0;
}

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

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

相关文章

玉柴集团用USB Server对U盾远程安全管控

在当今数字化时代&#xff0c;企业的业务规模和组织结构日益复杂&#xff0c;对于U盾这样小小的&#xff0c;但却异常重要的USB设备的管理和使用提出了更高的要求。广西玉柴机器股份有限公司作为一家综合性集团企业&#xff0c;其业务规模庞大&#xff0c;组织结构复杂&#xf…

MapReduce(林子雨慕课课程)

文章目录 7. MapReduce7.1 MapReduce简介7.1.1 分布式并行编程7.1.2 MapReduce模型简介 7.2 MapReduce体系结构7.3 MapReduce工作流程概述7.4 Shuffle过程原理7.5 MapReduce应用程序的执行过程7.6 WordCount实例分析7.7 MapReduce的具体应用7.8 MaReduce编程实践 7. MapReduce …

案例研究|DataEase助力无锡布勒业务数据可视化建设

布勒集团是一家来自瑞士的家族企业&#xff0c;在谷物与食品以及先进材料制造等领域深耕超过160年。布勒大中华区的总部位于江苏无锡。无锡布勒是一家集研发、生产、销售于一体的综合性公司&#xff0c;拥有先进的生产设备及高素质的科技研发人员&#xff0c;以谷物深加工、谷物…

代码随想录第41天 | 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III /*** param {number[]} prices* return {number}*/ var maxProfit function (prices) {const len prices.lengthconst dp new Array(len).fill(0).map(x > new Array(5).fill(0));// 第一天买入&#xff08;第一次买入&#xff09;dp[0][1] …

c 语言基础题目:PTA L1-033 出生年

以上是新浪微博中一奇葩贴&#xff1a;“我出生于1988年&#xff0c;直到25岁才遇到4个数字都不相同的年份。”也就是说&#xff0c;直到2013年才达到“4个数字都不相同”的要求。本题请你根据要求&#xff0c;自动填充“我出生于y年&#xff0c;直到x岁才遇到n个数字都不相同的…

Jetson Orin NX 开发指南(2): 基本环境配置

本文主要是在 Jetson Orin NX 系统烧录和组件安装完成后&#xff0c;对系统进行一些基本的配置&#xff0c;需要注意的是这里的系统其实也是 ubuntu 系统&#xff0c;并且由于选择的是 &#xff0c;其对应的是 ubuntu 20.04 系统&#xff0c;接下来我将介绍一些基本的配置。 一…

【动态规划】是泰波那契数,不是斐波那契数

Problem: 1137. 第 N 个泰波那契数 文章目录 题目解读解题方法dp动态规划迭代优化✔ 复杂度Code 题目解读 首先我们来解读一下本题的意思&#x1f50d; 相信读者在看到【泰波那契数】的时候&#xff0c;不禁会联想到【斐波那契数】&#xff0c;它们呢是一对孪生兄弟&#xff0c…

【d2l动手学深度学习】 Lesson 10 多层感知机 + 代码实现 试验结果对比

文章目录 1. 介绍2. 单层Softmax回归2.1 手写Softmax训练效果 2.2 调用pytorch内置的softmax回归层实现调用pytorch内置softmax实验结果总结 3. 一层感知机&#xff08;MLP&#xff09; Softmax实验结果 Reference写在最后 1. 介绍 在第十节课 多层感知机 的代码实现部分&…

前后端分离项目-基于springboot+vue的足球青训俱乐部管理后台系统的设计与实现(内含代码+文档+报告)

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

4个不限字数的AI智能写作网站,用好任意一个就可以了

我们都在互联网上写过内容&#xff0c;有的人写社交媒体帖子、电子邮件或文本&#xff0c;有的人为我们的网站、产品描述、视频内容、广告甚至客户支持撰写内容。最近&#xff0c;*******推出了友好的类似聊天机器人的界面&#xff0c;使得AI写作更加容易访问&#xff0c;并迅速…

JVM上篇之类加载子系统

目录 类加载子系统 内存结构 类的生命周期 类的加载过程 加载 加载class文件方式 连接 验证 验证阶段 准备 解析 初始化 类加载器 介绍 作用 分类 引导类加载器 自定义类加载器 ClassLoader 获取ClassLoader途径 双亲委派机制 介绍 执行流程 好处 打破…

01-RocketMQ整体理解与快速实战

上一篇&#xff1a;RocketMQ从入门到精通汇总 一、MQ介绍 1、什么是MQ&#xff1f;为什么要用MQ&#xff1f; MQ&#xff1a;MessageQueue&#xff0c;消息队列。 队列&#xff0c;是一种FIFO 先进先出的数据结构。消息由生产者发送到MQ进行排队&#xff0c;然后按原来的顺序…

解决 Centos 安装 Python 3.10 的报错: Could not import runpy module

操作环境&#xff1a;CentOS 7、Gcc 4.8.5、Python 3.10.0 系统上已经有 2.x&#xff0c;3.6 版本的 Python 了&#xff0c;但是还是想装一个 3.10 的。因为刚写的脚本文件是较高版本的&#xff0c;在 3.6 上无法正常运行&#xff0c;Python 语法不是很了解&#xff0c;只能从…

[每周一更]-(第66期):Docker 守护进程说明

Docker 的优势 Build once, Run anywhere 上面这句话很精辟的总结了 docker 的优点。我从下面几点具体描述 docker 带给开发者的能力 应用标准化 无论什么语言开发的应用&#xff0c;我们都能用 dockerfile 和构建脚本方便的进行应用构建打包&#xff0c;代码库 构建 regis…

华为交换机vlan划分、telnet 管理地址配置

------1--- 1台核心交换时s5700 2台汇聚交换机S3700 6台PC -----2------ 创建vlan 10 20 30 s3700下PC1,PC2,PC3 S3700下PC4,PC5,PC6 VLAN10 PC1,PC2 VLAN20 PC3,PC4 VLAN30 PC5,PC6 -------3----- 要求实现&#xff1a; PC1,PC2互通&#xff1b; PC3,PC4互通&#xff1b; P…

【吞噬星空4】徐欣因祸得福,罗峰强势复仇,两大强者被杀,阿特金已开始自救

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析吞噬星空国漫。 吞噬星空第89集预告已经出来了&#xff0c;从预告来看&#xff0c;信息量是真的多。从徐欣因祸得福到罗峰强势复仇&#xff0c;再到两大强者被杀&#xff0c;乃至于最后的阿特金已开始自救。那么多的不说&…

3分钟轻松实现网关网口远程监控安川PLC

EG网关网口连接安川PLC 目录 EG网关网口连接安川PLC 一. 准备工作 1.1 在对接前我们需准备如下物品 1.2 EG20网关准备工作 1.3 PLC准备工作 1.4 添加MEMOBUS协议 二. EMCP平台设置 2.1 新增EG设备 2.2 远程配置网关 2.3 网关绑定 2.4 通讯参数设置 2.5 创建设备驱动…

以单颗CMOS摄像头重构三维场景,维悟光子发布单目红外3D成像模组

维悟光子近期发布全新单目红外3D成像模组,现可提供下游用户进行测试导入。通过结合微纳光学元件编码和人工智能算法解码,维悟光子单目红外3D成像模组采用单颗摄像头,通过单帧拍摄,可同时获取像素级配准的3D点云和红外图像信息,可被应用于机器人、生物识别等广阔领域。 市场…

vxe是一款功能强大的table,有vue2/3版本

vxe-table v4https://vxetable.cn/#/table/start/install 当计算上千&#xff0c;上万条数据的和&#xff0c;或者算数平方根时可以使用web worker&#xff0c;来实现复杂&#xff0c;大量的计算&#xff0c;同时也不会造成浏览器的卡顿&#xff0c;暂时只是知道&#xff0c;还…

rxjava2源码分析

目录 一&#xff0c;Observable调用流程 1.1 简单Observable.create()创建调用流程 1.2 map操作符 1.3 flatmap操作符 1.4 subscribeOn操作符 1.5 observeOn操作符 一&#xff0c;Observable调用流程 1.1 简单Observable.create()创建调用流程 上面的这个流程图是下面这…