算法设计与分析-上机实验9

P161
6.设计一个算法求出根节点到叶子结点的所有路径

// By SnowDream
#include <bits/stdc++.h>
using namespace std;

// 定义二叉树节点
typedef struct node {
    int data; // 数据元素
    struct node *lchild; // 指向左孩子结点
    struct node *rchild; // 指向右孩子结点
} Node;

// 递归查找路径
void findPathsHelper(Node* node, const string& path, vector<string>& paths) {
    if (node != nullptr) {
        // 将当前节点添加到路径中
        stringstream ss;
        ss << node->data;
        string strVal = ss.str();

        if (node->lchild == nullptr && node->rchild == nullptr) { // 如果到达叶子节点
            paths.push_back(path + strVal); // 记录完整路径
        } else {
            // 如果不是叶子节点,则继续向下搜索
            findPathsHelper(node->lchild, path + strVal + "->", paths);
            findPathsHelper(node->rchild, path + strVal + "->", paths);
        }
    }
}

// 返回从根到叶子的所有路径
vector<string> findPaths(Node* root) {
    vector<string> paths;
    if (root != nullptr) {
        findPathsHelper(root, "", paths);
    }
    return paths;
}

// 构建二叉树
Node* buildTree(vector<string>& nodes) {
    if (nodes.empty() || nodes[0] == "#") 
        return nullptr;
    Node* root = new Node{stoi(nodes[0]), nullptr, nullptr};
    queue<Node*> q;
    q.push(root);
    int i = 1;
    while (!q.empty() && i < nodes.size()) {
        Node* current = q.front();
        q.pop();
        if (nodes[i] != "#") {
            current->lchild = new Node{stoi(nodes[i]), nullptr, nullptr};
            q.push(current->lchild);
        }
        i++;
        if (i < nodes.size() && nodes[i] != "#") {
            current->rchild = new Node{stoi(nodes[i]), nullptr, nullptr};
            q.push(current->rchild);
        }
        i++;
    }
    return root;
}

void DestroyTree(Node* node) {
    if (node != nullptr) {
        DestroyTree(node->lchild);
        DestroyTree(node->rchild);
        delete node;
    }
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    vector<string> input = {"1", "2", "3", "#", "5"};
    Node* root = buildTree(input);
    vector<string> paths = findPaths(root);
    for (const auto& path : paths) {
        cout << path << endl;
    }
    DestroyTree(root);
    return 0;
}

P162
9.给出一个 n * m的矩阵,每个点有一个权值,从矩阵左下走到右上(可以走四个方向),让你找到一条路径 使得该路径所路过的权值和最小,输出最小权值和。

// By SnowDream
#include <bits/stdc++.h>
using namespace std;

int minPathSum(vector<vector<int>>& grid) {
    int n = (int)grid.size();
    if (n == 0) return 0;
    int m = (int)grid[0].size();
    vector<vector<int>> dp(n, vector<int>(m, INT_MAX));

    // 初始化起点
    dp[n-1][0] = grid[n-1][0];

    // 使用优先队列来实现Dijkstra算法
    priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<>> pq;
    pq.push({grid[n-1][0], {n-1, 0}});

    while (!pq.empty()) {
        auto current = pq.top();
        pq.pop();

        int dist = current.first;
        int x = current.second.first;
        int y = current.second.second;

        // 如果已经找到了到达右上角的路径,则返回结果
        if (x == 0 && y == m-1) return dist;

        // 检查四个方向
        int dx[] = {-1, 1, 0, 0};
        int dy[] = {0, 0, -1, 1};

        for (int i = 0; i < 4; ++i) {
            int newX = x + dx[i];
            int newY = y + dy[i];

            if (newX >= 0 && newX < n && newY >= 0 && newY < m) {
                int newDist = dist + grid[newX][newY];

                // 只有当找到更短的路径时才更新并加入队列
                if (newDist < dp[newX][newY]) {
                    dp[newX][newY] = newDist;
                    pq.push({newDist, {newX, newY}});
                }
            }
        }
    }

    return dp[0][m-1];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    vector<vector<int>> grid = {{1,1,1},{1,1,1},{1,1,1}};
    cout << "最小路径和: " << minPathSum(grid) << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值