广度优先算法代码示例:
using System;
using System.Collections.Generic;
public class DijkstraAlgorithm
{
// Dijkstra算法主要逻辑
public static void Dijkstra(Dictionary<int, List<Edge>> graph, int startNode, int endNode)
{
// 存储节点到起点的距离
Dictionary<int, int> distances = new Dictionary<int, int>();
// 存储节点的父节点,用于构建最短路径
Dictionary<int, int> parents = new Dictionary<int, int>();
// 优先队列,用于按照节点距离从小到大的顺序处理
PriorityQueue priorityQueue = new PriorityQueue();
// 初始化distances和parents字典
foreach (int node in graph.Keys)
{
distances[node] = int.MaxValue; // 将所有节点的距离初始化为无穷大
parents[node] = -1; // 将所有节点的父节点初始化为-1
}
distances[startNode] = 0; // 将起始节点的距离设置为0
priorityQueue.Enqueue(new Node(startNode, 0)); // 将起始节点加入优先队列
// 开始执行Dijkstra算法
while (priorityQueue.Count > 0) // 当优先队列不为空时
{
Node currentNode = priorityQueue.Dequeue();
// 如果当前节点的距离值大于distances中对应节点的距离值,说明当前节点已经被处理过,直接跳过
if (currentNode.Value > distances[currentNode.Vertex])
continue;
// 对当前节点的所有相邻边进行遍历
foreach (Edge edge in graph[currentNode.Vertex])
{
// 计算从起始节点经过当前节点到目标节点的新距离
int newDistance = distances[currentNode.Vertex] + edge.Weight;
// 如果新距离小于distances中对应节点的距离值
if (newDistance < distances[edge.Destination])
{
distances[edge.Destination] = newDistance; // 更新目标节点的距离值
parents[edge.Destination] = currentNode.Vertex; // 更新目标节点的父节点
priorityQueue.Enqueue(new Node(edge.Destination, newDistance)); // 将目标节点加入优先队列
}
}
}
// 判断是否存在从起点到终点的路径
if (distances[endNode] == int.MaxValue)
{
Console.WriteLine("There is no path from startNode to endNode.");
}
else
{
// 获取最短路径
List<int> shortestPath = GetShortestPath(parents, startNode, endNode);
Console.WriteLine($"Shortest distance from {startNode} to {endNode}: {distances[endNode]}");
Console.WriteLine("Shortest path: " + string.Join(" -> ", shortestPath));
}
}
// 构建最短路径
public static List<int> GetShortestPath(Dictionary<int, int> parents, int startNode, int endNode)
{
List<int> path = new List<int>();
int currentNode = endNode;
while (currentNode != -1)
{
path.Insert(0, currentNode); // 将节点插入到路径列表的开头
currentNode = parents[currentNode]; // 更新当前节点为父节点
}
return path;
}
public static void Main(string[] args)
{
Dictionary<int, List<Edge>> graph = new Dictionary<int, List<Edge>>();
// 创建图形
// 每个键表示一个节点,每个值表示与该节点相连的所有边
graph[0] = new List<Edge>
{
new Edge(1, 2),
new Edge(2, 5),
new Edge(3, 9)
};
graph[1] = new List<Edge>
{
new Edge(4, 12)
};
graph[2] = new List<Edge>
{
new Edge(4, 5),
new Edge(5, 6)
};
graph[3] = new List<Edge>
{
new Edge(5, 10)
};
graph[4] = new List<Edge>
{
new Edge(6, 6)
};
graph[5] = new List<Edge>
{
new Edge(6, 5),
new Edge(7, 4)
};
graph[6] = new List<Edge>
{
new Edge(8, 8)
};
graph[7] = new List<Edge>
{
new Edge(8, 5),
new Edge(9, 7)
};
graph[8] = new List<Edge>
{
new Edge(9, 8)
};
graph[9] = new List<Edge>();
int startNode = 0;
int endNode = 9;
// 执行Dijkstra算法
Dijkstra(graph, startNode, endNode);
}
}
// 边类,表示节点之间的连接关系
public class Edge
{
public int Destination { get; } // 目标节点
public int Weight { get; } // 边的权重
public Edge(int destination, int weight)
{
Destination = destination;
Weight = weight;
}
}
// 节点类,包含节点编号和距离值
public class Node
{
public int Vertex { get; } // 节点编号
public int Value { get; } // 节点距离值
public Node(int vertex, int value)
{
Vertex = vertex;
Value = value;
}
}
// 优先队列类,用于保存节点,并确保按照节点的距离值从小到大排序
public class PriorityQueue
{
private List<Node> heap; // 存放节点的列表
public int Count => heap.Count;
public PriorityQueue()
{
heap = new List<Node>();
}
// 入队操作,将节点加入优先队列并保持有序
public void Enqueue(Node item)
{
heap.Add(item);
int currentIndex = heap.Count - 1;
while (currentIndex > 0)
{
int parentIndex = (currentIndex - 1) / 2;
if (heap[currentIndex].Value >= heap[parentIndex].Value)
break;
Swap(currentIndex, parentIndex);
currentIndex = parentIndex;
}
}
// 出队操作,取出距离值最小的节点
public Node Dequeue()
{
if (Count == 0)
throw new InvalidOperationException("PriorityQueue is empty.");
Node item = heap[0];
heap[0] = heap[Count - 1];
heap.RemoveAt(Count - 1);
int currentIndex = 0;
while (currentIndex < Count)
{
int leftChildIndex = 2 * currentIndex + 1;
int rightChildIndex = 2 * currentIndex + 2;
if (leftChildIndex >= Count)
break;
int smallerChildIndex = leftChildIndex;
if (rightChildIndex < Count && heap[rightChildIndex].Value < heap[leftChildIndex].Value)
smallerChildIndex = rightChildIndex;
if (heap[currentIndex].Value <= heap[smallerChildIndex].Value)
break;
Swap(currentIndex, smallerChildIndex);
currentIndex = smallerChildIndex;
}
return item;
}
// 交换两个位置的节点
private void Swap(int index1, int index2)
{
Node temp = heap[index1];
heap[index1] = heap[index2];
heap[index2] = temp;
}
}
注释很详细!