路径打印函数总结(递归回溯法)

路径打印函数总结(递归回溯法)

核心思想

通过逆序回溯的方式,从终点沿着前驱记录反向追踪到起点,利用后序打印保证路径方向正确。


通用实现模板

// 假设存储结构的定义
struct Node {
    int x, y;
    char dir; // 记录到达此节点的方向
} pre[MAX][MAX];

void print_path(int end_x, int end_y) {
    if (end_x == start_x && end_y == start_y) return; // 递归终止条件
    
    // 根据方向标记查找前驱节点
    switch(pre[end_x][end_y].dir) {
        case 'D': print_path(end_x - 1, end_y); break; // 来自上方
        case 'L': print_path(end_x, end_y + 1); break; // 来自右侧
        case 'R': print_path(end_x, end_y - 1); break; // 来自左侧
        case 'U': print_path(end_x + 1, end_y); break; // 来自下方
    }
    
    cout << pre[end_x][end_y].dir; // 后序打印保证正向输出
}

或者:

void print_path(int x,int y){
	if(x==1 && y==1) return;
	if(pre[x][y]=='D') print_path(x-1,y);
	if(pre[x][y]=='L') print_path(x,y+1);
	if(pre[x][y]=='R') print_path(x,y-1);
	if(pre[x][y]=='U') print_path(x+1,y);
	cout<<pre[x][y];
}

关键实现要素

要素说明
1. 前驱信息存储使用二维数组/矩阵记录每个节点的来源方向(示例中的pre[][]
2. 递归终止条件当回溯到起点时停止递归
3. 方向映射机制明确不同方向字符对应的坐标变化规则
4. 后序打印策略在递归返回时输出方向字符,保证路径顺序正确

通用问题解决步骤

  1. 定义方向映射

    // 建议使用标准方向定义
    const int dx[] = {-1,1,0,0};  // 上、下、左、右
    const int dy[] = {0,0,-1,1};
    const char dirs[] = {'U','D','L','R'};
    
  2. 记录前驱信息

    • 在搜索过程中记录每个节点的来源方向
    if(!visited[nx][ny]) {
        visited[nx][ny] = true;
        pre[nx][ny] = {cur.x, cur.y, dirs[i]};
        q.push({nx, ny});
    }
    
  3. 递归回溯打印

    • 从终点开始反向追踪路径
    • 使用后序遍历保证输出顺序

扩展应用场景

场景适配方法
多维路径搜索增加pre数组维度,如pre[x][y][z]
加权路径/最短路径配合Dijkstra算法,记录前驱节点和路径权重
多目标路径记录使用vector存储多条路径,通过DFS遍历所有可能前驱
非递归实现改用栈结构存储路径节点,通过迭代方式输出

注意事项

  1. 递归深度限制

    • 当路径长度超过1e4时可能栈溢出
    • 解决方案:改用迭代方式存储路径
    void iterative_print(int end_x, int end_y) {
        stack<char> path;
        while(end_x != start_x || end_y != start_y) {
            path.push(pre[end_x][end_y].dir);
            // 更新坐标到前驱位置...
        }
        while(!path.empty()) {
            cout << path.top();
            path.pop();
        }
    }
    
  2. 方向映射一致性

    • 必须保证BFS搜索时使用的方向顺序与打印时的解析顺序一致
  3. 多解处理

    • 如果需要记录所有最短路径,改用vector存储前驱节点列表
    vector<DirInfo> pre[MAX][MAX]; // 每个节点可能有多个前驱
    

复杂度分析

方法时间复杂度空间复杂度适用场景
递归回溯O(path_length)O(path_length)路径长度较小
迭代栈实现O(path_length)O(path_length)超长路径
多路径记录O(2^n)O(2^n)需要输出所有可能路径

掌握这种路径记录与回溯方法,可以解决绝大多数网格类路径搜索问题的结果输出需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值