当前位置:   article > 正文

矿大数据结构 实验三_中国矿业大学 数据结构实验

中国矿业大学 数据结构实验

A.二叉链表存储的二叉树

定义节点 --- 建立二叉树的函数 --- 前序遍历函数 --- 中序遍历函数

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. struct Node{ //节点,用char存储本身的数据,指针指向左右节点
  5. char data;
  6. Node *lc;
  7. Node *rc;
  8. Node(char c):data(c),lc(NULL),rc(NULL){}
  9. };
  10. Node* build(string s,int& i){ //i代表当前的位置
  11. if(i>=s.length()||s[i]==' ') return NULL;
  12. Node* root = new Node(s[i]);
  13. i++;
  14. root->lc=build(s,i);
  15. i++;
  16. root->rc=build(s,i);
  17. return root;
  18. }
  19. void pre_order(Node *root){
  20. if(root==NULL) return;
  21. cout<<root->data<<' ';
  22. pre_order(root->lc);
  23. pre_order(root->rc);
  24. }
  25. void mid_order(Node*root){
  26. if(root==NULL) return ;
  27. mid_order(root->lc);
  28. cout<<root->data<<' ';
  29. mid_order(root->rc);
  30. }
  31. void midord(Node *root){
  32. }
  33. int main() {
  34. string s;
  35. getline(cin,s);
  36. int i=0;
  37. Node *root = build(s,i);
  38. pre_order(root);
  39. cout<<'\n';
  40. mid_order(root);
  41. cout<<'\n';
  42. mid_order(root);
  43. }

B.哈夫曼树

  1. #include <iostream>
  2. #include <queue>
  3. #include <vector>
  4. using namespace std;
  5. //定义一个结点类,包含权值和左右子结点
  6. class Node {
  7. public:
  8. int weight;
  9. Node* left;
  10. Node* right;
  11. Node(int w) {
  12. weight = w;
  13. left = NULL;
  14. right = NULL;
  15. }
  16. };
  17. //定义一个比较函数,用于优先队列的排序
  18. struct cmp {
  19. bool operator()(Node* a, Node* b) {
  20. return a->weight > b->weight; //权值小的优先
  21. }
  22. };
  23. //计算哈夫曼树的权值和
  24. int huffmanSum(Node* root, int depth) {
  25. if (root == NULL) return 0; //空结点返回0
  26. if (root->left == NULL && root->right == NULL) return root->weight * depth; //叶子结点返回权值乘以深度
  27. return huffmanSum(root->left, depth + 1) + huffmanSum(root->right, depth + 1); //非叶子结点递归计算左右子树的和
  28. }
  29. int main() {
  30. int n; //叶结点个数
  31. while (cin >> n) { //多组输入
  32. priority_queue<Node*, vector<Node*>, cmp> pq; //创建一个优先队列,用于存储结点指针
  33. for (int i = 0; i < n; i++) {
  34. int w; //输入权值
  35. cin >> w;
  36. Node* node = new Node(w); //创建一个新的结点
  37. pq.push(node); //将结点指针入队
  38. }
  39. while (pq.size() > 1) { //当队列中还有多于一个结点时,循环执行以下操作
  40. Node* left = pq.top(); //取出队首的最小权值结点,作为左子结点
  41. pq.pop(); //出队
  42. Node* right = pq.top(); //取出队首的次小权值结点,作为右子结点
  43. pq.pop(); //出队
  44. Node* parent = new Node(left->weight + right->weight); //创建一个新的父结点,其权值为左右子结点的和
  45. parent->left = left; //连接左子结点
  46. parent->right = right; //连接右子结点
  47. pq.push(parent); //将父结点入队
  48. }
  49. Node* root = pq.top(); //最后队列中只剩一个结点,即为哈夫曼树的根结点
  50. cout << huffmanSum(root, 0) << endl; //输出哈夫曼树的权值和,初始深度为0
  51. }
  52. return 0;
  53. }

C.

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. vector<int> in, pre, post;
  5. bool unique = true;
  6. void getIn(int preLeft, int preRight, int postLeft, int postRight) {
  7. if(preLeft == preRight) {
  8. in.push_back(pre[preLeft]);
  9. return;
  10. }
  11. if (pre[preLeft] == post[postRight]) {
  12. int i = preLeft + 1;
  13. while (i <= preRight && pre[i] != post[postRight-1]) i++;
  14. if (i - preLeft > 1)
  15. getIn(preLeft + 1, i - 1, postLeft, postLeft + (i - preLeft - 1) - 1);
  16. else
  17. unique = false;
  18. in.push_back(post[postRight]);
  19. getIn(i, preRight, postLeft + (i - preLeft - 1), postRight - 1);
  20. }
  21. }
  22. int main() {
  23. int n;
  24. scanf("%d", &n);
  25. pre.resize(n), post.resize(n);
  26. for (int i = 0; i < n; i++)
  27. scanf("%d", &pre[i]);
  28. for (int i = 0; i < n; i++)
  29. scanf("%d", &post[i]);
  30. getIn(0, n-1, 0, n-1);
  31. printf("%s\n%d", unique == true ? "Yes" : "No", in[0]);
  32. for (int i = 1; i < in.size(); i++)
  33. printf(" %d", in[i]);
  34. printf("\n");
  35. return 0;
  36. }

D.最短路径

dfs搜索即可。记得开long long

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int MAXN = 1e5;
  5. int n,m;
  6. int len[150][150];
  7. bool t[150][150];
  8. bool is[150][150];
  9. ll ans=0;
  10. void dfs(int x,int y,int cnt){
  11. if(x==y){
  12. if(ans==0){
  13. ans=cnt;
  14. }
  15. else {
  16. if(ans>cnt)
  17. ans=cnt;
  18. }
  19. return ;
  20. }
  21. for(int i=1;i<=n;i++){
  22. if(i==x) continue;
  23. if(len[x][i]!=0&&is[x][i]!=1){
  24. is[x][i]=1;
  25. dfs(i,y,cnt+len[x][i]);
  26. }
  27. }
  28. }
  29. int main(){
  30. cin>>n>>m;
  31. int x,y,z;
  32. for(int i=1;i<=m;i++){
  33. cin>>x>>y>>z;
  34. len[x][y]=z;
  35. }
  36. cin>>x>>y;
  37. dfs(x,y,0);
  38. ans==0? cout<<"STOP":cout<<ans;
  39. return 0;
  40. }

E.

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. const int INF = 0x3f3f3f3f; // 定义一个无穷大的常量,用于表示没有直接连接的情况
  5. struct Edge {
  6. int from; // 边的起点
  7. int to; // 边的终点
  8. int cost; // 边的代价
  9. Edge(int f, int t, int c): from(f), to(t), cost(c) {} // 构造函数
  10. };
  11. int prim(vector<vector<int>>& graph, vector<Edge>& tree) { // 根据邻接矩阵构建最小生成树,并返回总代价
  12. int n = graph.size(); // 图中顶点的个数
  13. vector<int> pre(n, -1); // 前驱数组,存储每个顶点的前驱顶点的索引,初始为-1
  14. vector<bool> visited(n, false); // 访问标记数组,初始为false
  15. vector<int> dist(n, INF); // 距离数组,存储每个顶点到当前生成树的最短距离,初始为无穷大
  16. int total = 0; // 总代价,初始为0
  17. dist[0] = 0; // 从第一个顶点开始构建最小生成树,将其距离设为0
  18. for (int i = 0; i < n; i++) { // 循环n次,每次加入一个顶点到最小生成树中
  19. int u = -1; // 用于寻找距离最小的顶点的索引,初始为-1
  20. int minDist = INF; // 用于记录最小距离,初始为无穷大
  21. for (int j = 0; j < n; j++) { // 遍历所有顶点
  22. if (!visited[j] && dist[j] < minDist) { // 如果该顶点没有被访问过,且其距离小于当前最小距离
  23. u = j; // 更新最小距离顶点的索引
  24. minDist = dist[j]; // 更新最小距离
  25. }
  26. }
  27. if (u == -1) return -1; // 如果没有找到合适的顶点,说明图不连通,返回-1
  28. visited[u] = true; // 将找到的顶点标记为已访问
  29. total += minDist; // 将最小距离加入总代价中
  30. if (i > 0) tree.push_back(Edge(u, pre[u], minDist)); // 如果不是第一个顶点,将对应的边加入最小生成树中,pre[u]表示u的前驱顶点
  31. for (int v = 0; v < n; v++) { // 遍历所有顶点,更新距离数组和前驱数组
  32. if (!visited[v] && graph[u][v] < dist[v]) { // 如果该顶点没有被访问过,且u到v的边的代价小于当前距离
  33. dist[v] = graph[u][v]; // 更新距离
  34. pre[v] = u; // 更新前驱
  35. }
  36. }
  37. }
  38. return total; // 返回总代价
  39. }
  40. int main() {
  41. int n; // 图中顶点的个数
  42. cin >> n; // 输入顶点个数
  43. vector<vector<int>> graph(n, vector<int>(n)); // 邻接矩阵,初始为n*n的二维向量
  44. vector<Edge> tree; // 最小生成树,初始为空
  45. for (int i = 0; i < n; i++) { // 输入邻接矩阵
  46. for (int j = 0; j < n; j++) {
  47. cin >> graph[i][j]; // 输入第i行第j列的元素,即i到j的边的代价,如果为0表示没有直接连接
  48. if (graph[i][j] == 0) graph[i][j] = INF; // 将0替换为无穷大,方便后续处理
  49. }
  50. }
  51. int result = prim(graph, tree); // 调用prim函数构建最小生成树,并得到总代价
  52. if (result == -1) { // 如果返回值为-1,说明图不连通
  53. cout << "The graph is not connected." << endl; // 输出提示信息
  54. } else { // 如果返回值不为-1,说明图连通
  55. cout << result << endl; // 输出总代价
  56. }
  57. return 0; // 程序结束
  58. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/790588
推荐阅读
相关标签
  

闽ICP备14008679号