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


    🎃欢迎大家前去观看我的算法设计与分析专栏: 算法设计与分析_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):

    1. package one;
    2. public class Three {
    3. public static void main(String[] args) {
    4. // TODO Auto-generated method stub
    5. 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 },
    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 },
    7. { 0, 7, 0, 0, 3, 0, 0, 8 }, { 0, 0, 0, 0, 0, 0, 0, 0 } };
    8. int s = 1;// 表示原点
    9. int[] dist = new int[x1.length];// 表示原点到各点的最短距离
    10. boolean[] visited = new boolean[x1.length];
    11. int [] pre=new int[x1.length];//记录最短路径的前驱结点
    12. for (int i = 0; i < x1.length; i++) {// 初始化
    13. dist[i] = Integer.MAX_VALUE;// 初始化为无穷大
    14. visited[i] = false;// 初始化为没有被访问过
    15. pre[i]=-1;//前去初始化为-1
    16. }
    17. dist[s - 1] = 0;// 自身到自身为0
    18. // 找原点到各个顶点的距离
    19. for (int i = 0; i < x1.length; i++) {
    20. int mindist = Integer.MAX_VALUE;// 最短路径
    21. int mindistindex = -1;// 最短路径的索引
    22. // 寻找路径中最短的
    23. for (int j = 0; j < x1.length; j++) {
    24. if (!(visited[j]) && dist[j] < mindist) {
    25. // 更新数据
    26. mindist = dist[j];
    27. mindistindex = j;
    28. }
    29. }
    30. visited[mindistindex] = true;// 将顶点添加到已访问数组中
    31. // 更新最短距离
    32. for (int j = 0; j < x1.length; j++) {
    33. if (!visited[j] && x1[mindistindex][j] != 0 && dist[mindistindex] != Integer.MAX_VALUE
    34. && dist[mindistindex] + x1[mindistindex][j] < dist[j]) {
    35. dist[j] = dist[mindistindex] + x1[mindistindex][j];// 更新最短距离
    36. pre[j]=mindistindex+1;//记录前驱结点
    37. }
    38. }
    39. }
    40. System.out.printf("顶点: ");
    41. for (int i = 0; i < x1.length; i++) {
    42. System.out.printf((i+1)+" ");
    43. }
    44. System.out.println();
    45. System.out.printf("距离: ");
    46. for (int i = 1; i < x1.length; i++) {
    47. System.out.printf(dist[i]+" ");
    48. }
    49. System.out.println();
    50. System.out.printf("前驱: ");
    51. for (int i = 1; i < x1.length; i++) {
    52. System.out.printf(pre[i]+" ");
    53. }
    54. }

    🎯运行结果:

    🎯 算法分析:

    时间复杂度:

    • 初始化阶段:需要遍历所有的顶点,时间复杂度为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语言程序:

    1. #include
    2. #include
    3. #include
    4. #define SIZE 8 // 矩阵大小
    5. void dijkstra(int graph[SIZE][SIZE], int source) {
    6. int dist[SIZE]; // 原点到各点的最短距离
    7. bool visited[SIZE]; // 记录节点是否被访问
    8. int pre[SIZE]; // 记录最短路径的前驱结点
    9. for (int i = 0; i < SIZE; i++) {
    10. dist[i] = INT_MAX; // 初始化为无穷大
    11. visited[i] = false; // 初始化为没有被访问过
    12. pre[i] = -1; // 前驱初始化为-1
    13. }
    14. dist[source - 1] = 0; // 自身到自身为0
    15. // 找原点到各个顶点的距离
    16. for (int i = 0; i < SIZE; i++) {
    17. int minDist = INT_MAX; // 最短路径
    18. int minDistIndex = -1; // 最短路径的索引
    19. // 寻找路径中最短的
    20. for (int j = 0; j < SIZE; j++) {
    21. if (!visited[j] && dist[j] < minDist) {
    22. minDist = dist[j];
    23. minDistIndex = j;
    24. }
    25. }
    26. visited[minDistIndex] = true; // 将顶点添加到已访问数组中
    27. // 更新最短距离
    28. for (int j = 0; j < SIZE; j++) {
    29. if (!visited[j] && graph[minDistIndex][j] != 0 && dist[minDistIndex] != INT_MAX &&
    30. dist[minDistIndex] + graph[minDistIndex][j] < dist[j]) {
    31. dist[j] = dist[minDistIndex] + graph[minDistIndex][j]; // 更新最短距离
    32. pre[j] = minDistIndex + 1; // 记录前驱结点
    33. }
    34. }
    35. }
    36. printf("顶点: ");
    37. for (int i = 0; i < SIZE; i++) {
    38. printf("%d ", i + 1);
    39. }
    40. printf("\n");
    41. printf("距离: ");
    42. for (int i = 1; i < SIZE; i++) {
    43. printf("%d ", dist[i]);
    44. }
    45. printf("\n");
    46. printf("前驱: ");
    47. for (int i = 1; i < SIZE; i++) {
    48. printf("%d ", pre[i]);
    49. }
    50. }
    51. int main() {
    52. int graph[SIZE][SIZE] = {
    53. {0, 2, 0, 1, 0, 3, 0, 0},
    54. {0, 0, 6, 0, 5, 0, 0, 0},
    55. {0, 0, 0, 0, 0, 0, 0, 6},
    56. {0, 10, 0, 0, 0, 0, 2, 0},
    57. {0, 0, 9, 0, 0, 0, 0, 4},
    58. {0, 0, 0, 5, 0, 0, 4, 0},
    59. {0, 7, 0, 0, 3, 0, 0, 8},
    60. {0, 0, 0, 0, 0, 0, 0, 0}
    61. };
    62. int source = 1; // 表示原点
    63. dijkstra(graph, source);
    64. return 0;
    65. }

    🎐python程序:

    1. import sys
    2. def dijkstra(x1, s):
    3. dist = [sys.maxsize] * len(x1) # 表示原点到各点的最短距离
    4. visited = [False] * len(x1)
    5. pre = [-1] * len(x1) # 记录最短路径的前驱结点
    6. dist[s - 1] = 0 # 自身到自身为0
    7. for _ in range(len(x1)):
    8. mindist = sys.maxsize # 最短路径
    9. mindistindex = -1 # 最短路径的索引
    10. # 寻找路径中最短的
    11. for j in range(len(x1)):
    12. if not visited[j] and dist[j] < mindist:
    13. # 更新数据
    14. mindist = dist[j]
    15. mindistindex = j
    16. visited[mindistindex] = True # 将顶点添加到已访问数组中
    17. # 更新最短距离
    18. for j in range(len(x1)):
    19. if not visited[j] and x1[mindistindex][j] != 0 and dist[mindistindex] != sys.maxsize and dist[mindistindex] + x1[mindistindex][j] < dist[j]:
    20. dist[j] = dist[mindistindex] + x1[mindistindex][j] # 更新最短距离
    21. pre[j] = mindistindex + 1 # 记录前驱结点
    22. print("顶点:", end=" ")
    23. for i in range(len(x1)):
    24. print(i + 1, end=" ")
    25. print()
    26. print("距离:", end=" ")
    27. for i in range(1, len(x1)):
    28. print(dist[i], end=" ")
    29. print()
    30. print("前驱:", end=" ")
    31. for i in range(1, len(x1)):
    32. print(pre[i], end=" ")
    33. print()
    34. if __name__ == "__main__":
    35. x1 = [[0, 2, 0, 1, 0, 3, 0, 0],
    36. [0, 0, 6, 0, 5, 0, 0, 0],
    37. [0, 0, 0, 0, 0, 0, 0, 6],
    38. [0, 10, 0, 0, 0, 0, 2, 0],
    39. [0, 0, 9, 0, 0, 0, 0, 4],
    40. [0, 0, 0, 5, 0, 0, 4, 0],
    41. [0, 7, 0, 0, 3, 0, 0, 8],
    42. [0, 0, 0, 0, 0, 0, 0, 0]]
    43. s = 1 # 表示原点
    44. dijkstra(x1, s)

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

    🎐C++程序:

    1. #include
    2. using namespace std;
    3. int main(){
    4. int x1[8][8]={{0,2,0,1,0,3,0,0},
    5. {0,0,6,0,5,0,0,0},
    6. {0,0,0,0,0,0,0,6},
    7. {0,10,0,0,0,0,2,0},
    8. {0,0,9,0,0,0,0,4},
    9. {0,0,0,5,0,0,4,0},
    10. {0,7,0,0,3,0,0,8},
    11. {0,0,0,0,0,0,0,0}};
    12. int s=1;
    13. const int n=8;
    14. int dist[n],pre[n];
    15. bool visited[n];
    16. for(int i=0;i
    17. dist[i]=INT_MAX;
    18. visited[i]=false;
    19. pre[i]=-1;
    20. }
    21. dist[s-1]=0;
    22. for(int i=0;i
    23. int mindist=INT_MAX,mindistindex=-1;
    24. for(int j=0;j
    25. if(!visited[j]&&dist[j]
    26. mindist=dist[j];
    27. mindistindex=j;
    28. }
    29. }
    30. visited[mindistindex]=true;
    31. for(int j=0;j
    32. if(!visited[j]&&x1[mindistindex][j]!=0&&dist[mindistindex]!=INT_MAX&&dist[mindistindex]+x1[mindistindex][j]
    33. dist[j]=dist[mindistindex]+x1[mindistindex][j];
    34. pre[j]=mindistindex+1;
    35. }
    36. }
    37. }
    38. cout<<"顶点: ";
    39. for(int i=0;i
    40. cout<1<<" ";
    41. }
    42. cout<
    43. cout<<"距离: ";
    44. for(int i=1;i
    45. cout<" ";
    46. }
    47. cout<
    48. cout<<"前驱: ";
    49. for(int i=1;i
    50. cout<" ";
    51. }
    52. cout<
    53. return 0;
    54. }
  • 相关阅读:
    一起Talk Android吧(第三百七十五回:如何使用ViewPager2)
    MQ高级-服务异步通信
    ProTable高级表格获取表单数据
    (免费领源码)hadoop#Mysql离线与实时的离线与实时的电影推荐系统10338-计算机毕业设计项目选题推荐
    设计模式浅析(六) ·命令模式
    用了10年开源工具,换了Smartbi后,3分钟搞定一份报表
    【2024】深度学习配置环境常见报错,持续更新中....
    【小程序】导航栏和内容页面联动效果实现
    分析java.lang.IncompatibleClassChangeError
    SSM框架(SpringBoot快速构建)
  • 原文地址:https://blog.csdn.net/shsjssnn/article/details/133687973