You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于C语言的BST节点最短路径规划及Dijkstra实现咨询

二叉搜索树中基于跳跃范围的最短路径规划问题

问题背景

给定一棵二叉搜索树(BST),节点数据结构定义如下:

struct Node
{
    int distance;
    int jumpRange;
    int visited; // 自行添加的字段,不确定是否合理
};

typedef struct Node *node;

字段说明:

  • distance:节点的位置值
  • jumpRange:从该节点出发,能到达的其他节点的最大距离范围(即目标节点的distance需满足 |当前节点distance - 目标节点distance| ≤ jumpRange)

需实现planTravel函数,调用示例:

int x = planTravel(root, 20, 50, &path);

参数与返回值说明:

  • root:BST根节点
  • start:起始位置的distance值
  • target:目标位置的distance值
  • path:存储最短路径的节点列表
  • 返回值x:路径包含的节点数量

当前函数框架:

int planTravel(node root, int start, int target, path *p)
{
    node *nodes = NULL;
    int count; // nodes数组中的节点数量
    nodes = find_nodes_where_value_inRange(root, start, target, target - start, &count); // 获取范围内的节点数组

    return 0;
}

核心需求

  • 找到从起始到目标的最短路径(路径节点数最少)
  • 若存在多条最短路径,选择节点位置更靠近起始位置的路径(例如:起始20到目标50,两条最短路径20-45-50和20-30-50,需返回后者)
  • 支持反向路径规划(如从50到20),因jumpRange限制,反向路径可能与正向不同

适配场景的Dijkstra算法伪代码

前置准备

  1. 为每个节点补充以下状态(可替代原visited字段,或扩展节点结构):
    • distance_from_start:从起始节点到当前节点的路径长度(节点数量),初始设为无穷大
    • prev_node:路径中当前节点的前驱节点,用于回溯路径
  2. 优先队列(最小堆):排序规则为先按路径长度升序,路径长度相同时,按节点distance与起始值的差值绝对值升序,确保优先选择更靠近起点的路径

伪代码实现

function planTravel(root, start, target, path):
    // 1. 获取所有可能关联的节点(可通过BST范围查询,覆盖起始、目标及跳跃可达的范围)
    nodes = find_relevant_nodes(root, start, target)
    start_node = find_node_by_distance(nodes, start)
    target_node = find_node_by_distance(nodes, target)

    // 2. 初始化节点状态
    for each node in nodes:
        node.distance_from_start = 无穷大
        node.prev_node = null
    start_node.distance_from_start = 1  // 起始节点自身算1个节点
    start_node.prev_node = null

    // 3. 初始化优先队列,元素格式:(路径长度, 节点distance值, 节点指针)
    priority_queue = [(1, start, start_node)]

    while priority_queue is not empty:
        // 取出当前最优节点:最短路径,路径相同则选更靠近起点的节点
        current_length, current_dist, current_node = extract_min(priority_queue)

        // 到达目标节点,提前终止循环
        if current_node == target_node:
            break

        // 若当前记录的路径长度已过时,跳过该节点
        if current_length > current_node.distance_from_start:
            continue

        // 4. 找到当前节点可跳跃到达的所有邻居
        neighbors = []
        for each node in nodes:
            if abs(current_node.distance - node.distance) ≤ current_node.jumpRange and node != current_node:
                add node to neighbors

        // 遍历邻居,更新路径状态
        for each neighbor in neighbors:
            new_length = current_length + 1
            // 情况1:找到更短的路径
            if new_length < neighbor.distance_from_start:
                neighbor.distance_from_start = new_length
                neighbor.prev_node = current_node
                add (new_length, neighbor.distance, neighbor) to priority_queue
            // 情况2:路径长度相同,但当前路径更靠近起点
            elif new_length == neighbor.distance_from_start:
                // 比较当前路径与原有路径的前驱节点,哪个更靠近起点
                existing_prev_diff = abs(neighbor.prev_node.distance - start)
                current_prev_diff = abs(current_node.distance - start)
                if current_prev_diff < existing_prev_diff:
                    neighbor.prev_node = current_node

    // 5. 回溯生成路径
    if target_node.prev_node == null and target_node != start_node:
        // 无可达路径
        return 0
    else:
        // 从目标节点回溯到起始节点,再反转得到正序路径
        current = target_node
        while current != null:
            add current to path
            current = current.prev_node
        reverse path
        return length of path

反向路径规划处理

反向路径规划只需交换start和target参数即可,无需修改核心逻辑——因为jumpRange的判断是基于当前节点到目标节点的距离绝对值,反向时只是起始点和终点互换,跳跃规则保持一致。


内容的提问来源于stack exchange,提问作者Luca Pedersoli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 01:57:41