鱼C论坛

 找回密码
 立即注册
查看: 719|回复: 28

[已解决]有没有大佬帮忙看看我的程序哪里出错了

[复制链接]
发表于 2023-12-11 19:40:34 | 显示全部楼层 |阅读模式
60鱼币


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. typedef int ElemType;
  5. typedef struct graph
  6. {
  7.     ElemType *v;  // 通过入栈的方式判断结点是否有被遍历
  8.     ElemType **p; // 邻接表矩阵
  9.     ElemType *stack;
  10. } graph;
  11. void Initialization(graph *ch, ElemType n)
  12. {
  13.     ch->p = (ElemType **)malloc(sizeof(ElemType *) * pow((n + 1), 2));
  14.     for (int i = 1; i <= n; i++)
  15.     {
  16.         ch->p[i] = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
  17.     }
  18.     ch->v = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
  19.     ch->stack = (ElemType *)malloc(sizeof(ElemType) * n);
  20. }
  21. void create(graph *ch, ElemType n)
  22. {
  23.     printf("请输入邻接表矩阵\n");
  24.     for (int i = 1; i <= n; i++)
  25.     {
  26.         for (int j = 1; j <= n; j++)
  27.         {
  28.             scanf("%d", &(ch->p[i][j]));
  29.         }
  30.     }
  31. }
  32. void visit(graph *ch, ElemType nn, ElemType n)
  33. {
  34.     int node = nn, j = 1, top = 0;
  35.     ch->v[nn] = 1;
  36.     ch->stack[top++] = nn;
  37.     printf("%d", nn);
  38.     while (1)
  39.     {
  40.         if (ch->p[node][j] == 1 && ch->v[j] == 0)
  41.         {
  42.             ch->v[j] = 1;
  43.             ch->stack[top++] = j;
  44.             printf("->%d", j);
  45.             node = j;
  46.             j = 1;
  47.         };
  48.         if (j == n + 1)
  49.         {
  50.             if (ch->stack[top] == nn)
  51.             {
  52.                 break;
  53.             }
  54.             ch->stack[top--] = 0;
  55.             node = ch->stack[top];
  56.             j = 1;
  57.         }
  58.         j++;
  59.     }
  60. }
  61. int main(void)
  62. {
  63.     int n, nn;
  64.     graph p;
  65.     do
  66.     {

  67.         printf("请输入结点数:");
  68.         scanf("%d", &n);
  69.         if (n <= 0)
  70.         {
  71.             printf("结点数不得小于等于0!\n");
  72.         }
  73.     } while (n <= 0);
  74.     Initialization(&p, n);
  75.     create(&p, n);
  76.     do
  77.     {

  78.         printf("请选择从哪个结点开始遍历:");
  79.         scanf("%d", &nn);
  80.         if (nn < 0 || nn > n)
  81.         {
  82.             printf("您的输入不正确!\n");
  83.         }
  84.     } while (nn < 0 || nn > n);
  85.     visit(&p, nn, n);
  86.     system("pause");
  87.     return 0;
  88. }
复制代码
最佳答案
2023-12-11 19:40:35
嗯,对于图来说,确实需要一个vector来标记已经访问过的节点,不然会死循环,因为有多条路径
改成这样,非递归的版本

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>

  5. typedef int ElemType;

  6. typedef struct {
  7.     ElemType e;
  8.     size_t status;
  9. } stack_elem_t;

  10. typedef struct {
  11.     stack_elem_t *data;
  12.     size_t size, top;
  13. } stack_t;

  14. stack_t *stack_init(void) {
  15.     stack_t *stack = malloc(sizeof(*stack));
  16.     stack->data = NULL;
  17.     stack->size = stack->top = 0;
  18.     return stack;
  19. }

  20. void stack_deinit(stack_t *stack) {
  21.     free(stack->data);
  22.     free(stack);
  23. }

  24. size_t stack_size(const stack_t *stack) {
  25.     return stack->top;
  26. }

  27. bool stack_empty(const stack_t *stack) {
  28.     return stack_size(stack) == 0;
  29. }

  30. void stack_push(stack_t *stack, stack_elem_t e) {
  31.     if(stack->top == stack->size)
  32.         stack->data = realloc(stack->data, sizeof(stack_elem_t) * (stack->size += 10));
  33.     stack->data[stack->top++] = e;
  34. }

  35. void stack_pop(stack_t *stack) {
  36.     if(stack_empty(stack)) return;
  37.     --stack->top;
  38. }

  39. stack_elem_t stack_top(const stack_t *stack) {
  40.     if(stack_empty(stack)) abort();
  41.     return stack->data[stack->top - 1];
  42. }

  43. typedef ElemType vector_elem_t;

  44. typedef struct {
  45.     vector_elem_t *data;
  46.     size_t size;
  47. } vector_t;

  48. vector_t *vector_init(void) {
  49.     vector_t *vector = malloc(sizeof(*vector));
  50.     vector->data = NULL;
  51.     vector->size = 0;
  52.     return vector;
  53. }

  54. void vector_deinit(vector_t *vector) {
  55.     free(vector->data);
  56.     free(vector);
  57. }

  58. size_t vector_size(const vector_t *vector) {
  59.     return vector->size;
  60. }

  61. size_t vector_empty(const vector_t *vector) {
  62.     return vector_size(vector) == 0;
  63. }

  64. void vector_set(vector_t *vector, size_t index, vector_elem_t e) {
  65.     if(index >= vector->size)
  66.         vector->data = realloc(vector->data, sizeof(vector_elem_t) * (vector->size = index + 1));
  67.     vector->data[index] = e;
  68. }

  69. vector_elem_t vector_get(const vector_t *vector, size_t index) {
  70.     if(index >= vector->size) abort();
  71.     return vector->data[index];
  72. }

  73. void vector_append(vector_t *vector, vector_elem_t e) {
  74.     vector_set(vector, vector_size(vector), e);
  75. }

  76. bool vector_find(const vector_t *vector, vector_elem_t e) {
  77.     for(size_t i = 0; i < vector_size(vector); ++i) {
  78.         if(vector_get(vector, i) == e) return true;
  79.     }
  80.     return false;
  81. }

  82. typedef struct {
  83.     ElemType **p;
  84.     size_t n;
  85. } graph;

  86. void Initialization(graph *ch, size_t n) {
  87.     ch->p = malloc(sizeof(ElemType *) * n);
  88.     for(int i = 0; i < n; i++) {
  89.         ch->p[i] = malloc(sizeof(ElemType) * n);
  90.     }
  91.     ch->n = n;
  92. }

  93. void graph_deinit(graph *graph) {
  94.     for(size_t i = 0; i < graph->n; ++i) free(graph->p[i]);
  95.     free(graph->p);
  96. }

  97. void create(graph *ch) {
  98.     printf("请输入邻接表矩阵\n");
  99.     for(int i = 0; i < ch->n; i++) {
  100.         for(int j = 0; j < ch->n; j++) {
  101.             scanf("%d", &ch->p[i][j]);
  102.         }
  103.     }
  104. }

  105. void visit(graph *ch, ElemType n) {
  106.     stack_t *stack = stack_init();
  107.     vector_t *vector = vector_init();
  108.     stack_elem_t se = {n, 0};
  109.     stack_push(stack, se);
  110.     while(!stack_empty(stack)) {
  111.         se = stack_top(stack);
  112.         switch(se.status) {
  113.             case 0:
  114.                 printf("%d\n", se.e);
  115.                 stack_pop(stack);
  116.                 stack_push(stack, (stack_elem_t){se.e, 1});
  117.                 vector_append(vector, se.e);
  118.                 for(size_t i = 0; i < ch->n; ++i) {
  119.                     if(ch->p[se.e][i] && !vector_find(vector, i)) stack_push(stack, (stack_elem_t){i, 0});
  120.                 }
  121.                 break;
  122.             case 1:
  123.                 stack_pop(stack);
  124.         }
  125.     }
  126.     vector_deinit(vector);
  127.     stack_deinit(stack);
  128. }

  129. int main(void) {
  130.     unsigned int n, nn;
  131.     graph p;
  132.     printf("请输入结点数:");
  133.     scanf("%u", &n);
  134.     Initialization(&p, n);
  135.     create(&p);
  136.     do {
  137.         printf("请选择从哪个结点开始遍历:");
  138.         scanf("%d", &nn);
  139.         if(nn > n) printf("您的输入不正确!\n");
  140.     } while(nn > n);
  141.     visit(&p, nn - 1);
  142.     graph_deinit(&p);
  143.     return 0;
  144. }
复制代码

最佳答案

查看完整内容

嗯,对于图来说,确实需要一个vector来标记已经访问过的节点,不然会死循环,因为有多条路径 改成这样,非递归的版本
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-11 19:40:35 | 显示全部楼层    本楼为最佳答案   
嗯,对于图来说,确实需要一个vector来标记已经访问过的节点,不然会死循环,因为有多条路径
改成这样,非递归的版本

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>

  5. typedef int ElemType;

  6. typedef struct {
  7.     ElemType e;
  8.     size_t status;
  9. } stack_elem_t;

  10. typedef struct {
  11.     stack_elem_t *data;
  12.     size_t size, top;
  13. } stack_t;

  14. stack_t *stack_init(void) {
  15.     stack_t *stack = malloc(sizeof(*stack));
  16.     stack->data = NULL;
  17.     stack->size = stack->top = 0;
  18.     return stack;
  19. }

  20. void stack_deinit(stack_t *stack) {
  21.     free(stack->data);
  22.     free(stack);
  23. }

  24. size_t stack_size(const stack_t *stack) {
  25.     return stack->top;
  26. }

  27. bool stack_empty(const stack_t *stack) {
  28.     return stack_size(stack) == 0;
  29. }

  30. void stack_push(stack_t *stack, stack_elem_t e) {
  31.     if(stack->top == stack->size)
  32.         stack->data = realloc(stack->data, sizeof(stack_elem_t) * (stack->size += 10));
  33.     stack->data[stack->top++] = e;
  34. }

  35. void stack_pop(stack_t *stack) {
  36.     if(stack_empty(stack)) return;
  37.     --stack->top;
  38. }

  39. stack_elem_t stack_top(const stack_t *stack) {
  40.     if(stack_empty(stack)) abort();
  41.     return stack->data[stack->top - 1];
  42. }

  43. typedef ElemType vector_elem_t;

  44. typedef struct {
  45.     vector_elem_t *data;
  46.     size_t size;
  47. } vector_t;

  48. vector_t *vector_init(void) {
  49.     vector_t *vector = malloc(sizeof(*vector));
  50.     vector->data = NULL;
  51.     vector->size = 0;
  52.     return vector;
  53. }

  54. void vector_deinit(vector_t *vector) {
  55.     free(vector->data);
  56.     free(vector);
  57. }

  58. size_t vector_size(const vector_t *vector) {
  59.     return vector->size;
  60. }

  61. size_t vector_empty(const vector_t *vector) {
  62.     return vector_size(vector) == 0;
  63. }

  64. void vector_set(vector_t *vector, size_t index, vector_elem_t e) {
  65.     if(index >= vector->size)
  66.         vector->data = realloc(vector->data, sizeof(vector_elem_t) * (vector->size = index + 1));
  67.     vector->data[index] = e;
  68. }

  69. vector_elem_t vector_get(const vector_t *vector, size_t index) {
  70.     if(index >= vector->size) abort();
  71.     return vector->data[index];
  72. }

  73. void vector_append(vector_t *vector, vector_elem_t e) {
  74.     vector_set(vector, vector_size(vector), e);
  75. }

  76. bool vector_find(const vector_t *vector, vector_elem_t e) {
  77.     for(size_t i = 0; i < vector_size(vector); ++i) {
  78.         if(vector_get(vector, i) == e) return true;
  79.     }
  80.     return false;
  81. }

  82. typedef struct {
  83.     ElemType **p;
  84.     size_t n;
  85. } graph;

  86. void Initialization(graph *ch, size_t n) {
  87.     ch->p = malloc(sizeof(ElemType *) * n);
  88.     for(int i = 0; i < n; i++) {
  89.         ch->p[i] = malloc(sizeof(ElemType) * n);
  90.     }
  91.     ch->n = n;
  92. }

  93. void graph_deinit(graph *graph) {
  94.     for(size_t i = 0; i < graph->n; ++i) free(graph->p[i]);
  95.     free(graph->p);
  96. }

  97. void create(graph *ch) {
  98.     printf("请输入邻接表矩阵\n");
  99.     for(int i = 0; i < ch->n; i++) {
  100.         for(int j = 0; j < ch->n; j++) {
  101.             scanf("%d", &ch->p[i][j]);
  102.         }
  103.     }
  104. }

  105. void visit(graph *ch, ElemType n) {
  106.     stack_t *stack = stack_init();
  107.     vector_t *vector = vector_init();
  108.     stack_elem_t se = {n, 0};
  109.     stack_push(stack, se);
  110.     while(!stack_empty(stack)) {
  111.         se = stack_top(stack);
  112.         switch(se.status) {
  113.             case 0:
  114.                 printf("%d\n", se.e);
  115.                 stack_pop(stack);
  116.                 stack_push(stack, (stack_elem_t){se.e, 1});
  117.                 vector_append(vector, se.e);
  118.                 for(size_t i = 0; i < ch->n; ++i) {
  119.                     if(ch->p[se.e][i] && !vector_find(vector, i)) stack_push(stack, (stack_elem_t){i, 0});
  120.                 }
  121.                 break;
  122.             case 1:
  123.                 stack_pop(stack);
  124.         }
  125.     }
  126.     vector_deinit(vector);
  127.     stack_deinit(stack);
  128. }

  129. int main(void) {
  130.     unsigned int n, nn;
  131.     graph p;
  132.     printf("请输入结点数:");
  133.     scanf("%u", &n);
  134.     Initialization(&p, n);
  135.     create(&p);
  136.     do {
  137.         printf("请选择从哪个结点开始遍历:");
  138.         scanf("%d", &nn);
  139.         if(nn > n) printf("您的输入不正确!\n");
  140.     } while(nn > n);
  141.     visit(&p, nn - 1);
  142.     graph_deinit(&p);
  143.     return 0;
  144. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-11 19:41:08 | 显示全部楼层
不知道为什么无法实现遍历
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-11 19:46:48 | 显示全部楼层
只能输出第一个结点
1702295170028.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-11 23:51:50 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>

  5. typedef int ElemType;

  6. typedef struct {
  7.     ElemType **p; // 邻接表矩阵
  8.     size_t n;
  9.     bool *flag;
  10.     /*
  11.     ElemType *v;  // 通过入栈的方式判断结点是否有被遍历
  12.     ElemType *stack;
  13.     */
  14. } graph;

  15. void Initialization(graph *ch, size_t n) {
  16.     ch->p = malloc(sizeof(ElemType *) * n);
  17.     // 要习惯了从0开始
  18.     for(int i = 0; i < n; i++) {
  19.         ch->p[i] = malloc(sizeof(ElemType) * n);
  20.     }
  21.     ch->flag = malloc(sizeof(bool) * n);
  22.     memset(ch->flag, false, sizeof(bool) * n);
  23.     ch->n = n;

  24.     /*
  25.     ch->v = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
  26.     ch->stack = (ElemType *)malloc(sizeof(ElemType) * n);
  27.     */
  28. }

  29. // 释放内存的函数呢?
  30. void graph_deinit(graph *graph) {
  31.     for(size_t i = 0; i < graph->n; ++i) free(graph->p[i]);
  32.     free(graph->p);
  33.     free(graph->flag);
  34. }

  35. void create(graph *ch) {
  36.     printf("请输入邻接表矩阵\n");
  37.     for(int i = 0; i < ch->n; i++) {
  38.         for(int j = 0; j < ch->n; j++) {
  39.             scanf("%d", &ch->p[i][j]);
  40.         }
  41.     }
  42. }

  43. void visit(graph *ch, ElemType n) {
  44.     if(ch->flag[n]) return;
  45.     ch->flag[n] = true;
  46.     printf("visit: %d\n", n);
  47.     for(size_t i = 0; i < ch->n; ++i) {
  48.         if(ch->p[n][i]) visit(ch, i);
  49.     }
  50.     ch->flag[n] = false;

  51.     // 没看懂
  52.     /*
  53.     int node = n - 1, j = 1, top = 0;
  54.     ch->v[n] = 1;
  55.     ch->stack[top++] = n;
  56.     printf("%zu", n);
  57.     while(1) {
  58.         if(ch->p[node][j] == 1 && ch->v[j] == 0) {
  59.             ch->v[j] = 1;
  60.             ch->stack[top++] = j;
  61.             printf("->%d", j);
  62.             node = j;
  63.             j = 1;
  64.         };
  65.         if(j == ch->n + 1) {
  66.             if(ch->stack[top] == n) {
  67.                 break;
  68.             }
  69.             ch->stack[top--] = 0;
  70.             node = ch->stack[top];
  71.             j = 1;
  72.         }
  73.         j++;
  74.     }
  75.     */
  76. }

  77. int main(void) {
  78.     unsigned int n, nn;
  79.     graph p;
  80.     printf("请输入结点数:");
  81.     scanf("%u", &n);
  82.     Initialization(&p, n);
  83.     create(&p);
  84.     do {
  85.         printf("请选择从哪个结点开始遍历:");
  86.         scanf("%d", &nn);
  87.         if(nn > n) printf("您的输入不正确!\n");
  88.     } while(nn > n);
  89.     visit(&p, nn - 1);
  90.     graph_deinit(&p);
  91.     return 0;
  92. }
复制代码

评分

参与人数 1荣誉 +5 贡献 +3 收起 理由
1613551 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-11 23:59:40 | 显示全部楼层
本帖最后由 人造人 于 2023-12-12 00:37 编辑

递归返回后会清除当前节点的访问标志,如果有多条路径的话,感觉会出问题,还是这样吧
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>

  5. typedef int ElemType;

  6. typedef struct {
  7.     ElemType **p; // 邻接表矩阵
  8.     size_t n;
  9.     bool *flag;
  10. } graph;

  11. void Initialization(graph *ch, size_t n) {
  12.     ch->p = malloc(sizeof(ElemType *) * n);
  13.     for(int i = 0; i < n; i++) {
  14.         ch->p[i] = malloc(sizeof(ElemType) * n);
  15.     }
  16.     ch->flag = malloc(sizeof(bool) * n);
  17.     ch->n = n;
  18. }

  19. void graph_deinit(graph *graph) {
  20.     for(size_t i = 0; i < graph->n; ++i) free(graph->p[i]);
  21.     free(graph->p);
  22.     free(graph->flag);
  23. }

  24. void create(graph *ch) {
  25.     printf("请输入邻接表矩阵\n");
  26.     for(int i = 0; i < ch->n; i++) {
  27.         for(int j = 0; j < ch->n; j++) {
  28.             scanf("%d", &ch->p[i][j]);
  29.         }
  30.     }
  31. }

  32. void visit_sub(graph *ch, ElemType n) {
  33.     if(ch->flag[n]) return;
  34.     ch->flag[n] = true;
  35.     printf("visit: %d\n", n);
  36.     for(size_t i = 0; i < ch->n; ++i) {
  37.         if(ch->p[n][i]) visit_sub(ch, i);
  38.     }
  39. }

  40. void visit(graph *ch, ElemType n) {
  41.     memset(ch->flag, false, sizeof(bool) * ch->n);
  42.     visit_sub(ch, n);
  43. }

  44. int main(void) {
  45.     unsigned int n, nn;
  46.     graph p;
  47.     printf("请输入结点数:");
  48.     scanf("%u", &n);
  49.     Initialization(&p, n);
  50.     create(&p);
  51.     do {
  52.         printf("请选择从哪个结点开始遍历:");
  53.         scanf("%d", &nn);
  54.         if(nn > n) printf("您的输入不正确!\n");
  55.     } while(nn > n);
  56.     visit(&p, nn - 1);
  57.     graph_deinit(&p);
  58.     return 0;
  59. }
复制代码

评分

参与人数 1荣誉 +5 贡献 +3 收起 理由
1613551 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-12 14:44:38 | 显示全部楼层
人造人 发表于 2023-12-11 23:59
递归返回后会清除当前节点的访问标志,如果有多条路径的话,感觉会出问题,还是这样吧

不好意思,还没时间仔细看,但是我昨天其实自己弄出来一个了

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef int ElemType;
  4. typedef struct graph
  5. {
  6.     ElemType *v;
  7.     ElemType **p;
  8.     ElemType *stack;
  9. } graph;
  10. void Initialization(graph *ch, ElemType n)
  11. {
  12.     ch->p = (ElemType **)malloc(sizeof(ElemType *) * (n + 1));
  13.     for (int i = 0; i <= n; i++)
  14.     {
  15.         ch->p[i] = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
  16.     }
  17.     ch->v = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
  18.     ch->stack = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
  19.     for (int i = 0; i <= n; i++)
  20.     {
  21.         ch->v[i] = 0;
  22.         ch->stack[i] = 0;
  23.     }
  24. }
  25. void create(graph *ch, ElemType n)
  26. {
  27.     printf("请输入邻接表矩阵\n");
  28.     for (int i = 1; i <= n; i++)
  29.     {
  30.         for (int j = 1; j <= n; j++)
  31.         {
  32.             scanf("%d", &(ch->p[i][j]));
  33.         }
  34.     }
  35. }
  36. void visit(graph *ch, ElemType nn, ElemType n)
  37. {
  38.     int node = nn, j = 1, top = 0;
  39.     ch->v[nn] = 1;
  40.     ch->stack[top++] = nn;
  41.     printf("%d", nn);
  42.     while (1)
  43.     {
  44.         if (ch->p[node][j] == 1 && ch->v[j] == 0)
  45.         {
  46.             ch->v[j] = 1;
  47.             ch->stack[top++] = j;
  48.             printf("->%d", j);
  49.             node = j;
  50.             j = 1;
  51.         }
  52.         if (j > n)
  53.         {
  54.             if (nn == ch->stack[top])
  55.             {
  56.                 break;
  57.             }
  58.             ch->stack[top--] = 0;
  59.             node = ch->stack[top];
  60.             j = 1;
  61.         }
  62.         j++;
  63.     }
  64. }
  65. int main(void)
  66. {
  67.     int n, nn;
  68.     graph p;
  69.     do
  70.     {
  71.         printf("请输入结点数:");
  72.         scanf("%d", &n);

  73.         if (n <= 0)
  74.         {
  75.             printf("结点数不得小于等于0!\n");
  76.         }
  77.     } while (n <= 0);
  78.     Initialization(&p, n);
  79.     create(&p, n);
  80.     do
  81.     {
  82.         printf("请选择从哪个结点开始遍历:");
  83.         scanf("%d", &nn);

  84.         if (nn < 1 || nn > n)
  85.         {
  86.             printf("您的输入不正确!\n");
  87.         }
  88.     } while (nn < 1 || nn > n);
  89.     visit(&p, nn, n);
  90.     system("pause");
  91.     for (int i = 0; i <= n; i++)
  92.     {
  93.         free(p.p[i]);
  94.     }
  95.     free(p.p);
  96.     free(p.v);
  97.     free(p.stack);
  98.     return 0;
  99. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-12 17:46:43 | 显示全部楼层
1613551 发表于 2023-12-12 14:44
不好意思,还没时间仔细看,但是我昨天其实自己弄出来一个了

没看懂visit函数
说一下思路
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-12 20:53:49 | 显示全部楼层
人造人 发表于 2023-12-12 17:46
没看懂visit函数
说一下思路

那个有点问题,我是模仿这位老哥的
https://fishc.com.cn/thread-206094-1-1.html
1702385559481.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-12 20:54:32 | 显示全部楼层
人造人 发表于 2023-12-12 17:46
没看懂visit函数
说一下思路

我没改出来他那种效果,于是我自己又重新写了一个
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef int ElemType;
  4. typedef struct Queue
  5. {
  6.     ElemType data;
  7.     Queue *Qnode;
  8. } Queue;
  9. typedef struct graph
  10. {
  11.     ElemType *v;
  12.     ElemType **p;
  13.     ElemType *stack;
  14.     Queue *Qhead;
  15.     Queue *Qtail;
  16. } graph;
  17. void Initialization(graph *ch, ElemType n);
  18. void create(graph *ch, ElemType n);
  19. void enqueue(graph *ch, int nn);
  20. int outqueue(graph *ch);
  21. void widevisit(graph *ch, ElemType nn, ElemType n);
  22. void depthvisit(graph *ch, ElemType nn, ElemType n);
  23. void input(int *n, int *nn, int *option);
  24. void freeG(graph *ch, int n);
  25. int main(void)
  26. {
  27.     int n, nn, option;
  28.     graph p;
  29.     input(&n, &nn, &option);
  30.     Initialization(&p, n);
  31.     create(&p, n);
  32.     option ? widevisit(&p, nn, n) : depthvisit(&p, nn, n);
  33.     freeG(&p, n);
  34.     system("pause");
  35.     return 0;
  36. }
  37. void Initialization(graph *ch, ElemType n)
  38. {
  39.     ch->p = (ElemType **)malloc(sizeof(ElemType *) * (n + 1));
  40.     for (int i = 0; i <= n; i++)
  41.     {
  42.         ch->p[i] = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
  43.     }
  44.     ch->v = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
  45.     ch->stack = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
  46.     for (int i = 0; i <= n; i++)
  47.     {
  48.         ch->v[i] = 0;
  49.         ch->stack[i] = 0;
  50.     }
  51.     ch->Qhead = ch->Qtail = NULL;
  52. }
  53. void create(graph *ch, ElemType n)
  54. {
  55.     printf("请输入邻接矩阵\n");
  56.     for (int i = 1; i <= n; i++)
  57.     {
  58.         for (int j = 1; j <= n; j++)
  59.         {
  60.             scanf("%d", &(ch->p[i][j]));
  61.         }
  62.     }
  63. }
  64. void enqueue(graph *ch, int nn)
  65. {
  66.     Queue *p = (Queue *)malloc(sizeof(Queue));
  67.     p->Qnode = NULL;
  68.     p->data = nn;
  69.     if (ch->Qhead == NULL)
  70.     {
  71.         ch->Qhead = ch->Qtail = p;
  72.     }
  73.     else
  74.     {
  75.         ch->Qtail->Qnode = p;
  76.         ch->Qtail = p;
  77.     }
  78. }
  79. int outqueue(graph *ch)
  80. {
  81.     if (ch->Qhead == NULL)
  82.     {
  83.         return -1;
  84.     }
  85.     Queue *Q = ch->Qhead;
  86.     int temp = Q->data;
  87.     ch->Qhead = ch->Qhead->Qnode;
  88.     if (ch->Qhead == NULL)
  89.     {
  90.         ch->Qtail = NULL;
  91.     }
  92.     free(Q);
  93.     return temp;
  94. }
  95. void widevisit(graph *ch, ElemType nn, ElemType n)
  96. {
  97.     printf("下面进行图的广度优先遍历\n");
  98.     int node = nn;
  99.     ch->v[nn] = 1;
  100.     enqueue(ch, nn);
  101.     while (ch->Qhead != NULL)
  102.     {
  103.         node = outqueue(ch);
  104.         if (node != nn)
  105.         {
  106.             printf("->");
  107.         }
  108.         printf("%c", 'A' + node - 1);
  109.         for (int i = 1; i <= n; i++)
  110.         {
  111.             if (ch->p[node][i] == 1 && ch->v[i] == 0)
  112.             {
  113.                 ch->v[i] = 1;
  114.                 enqueue(ch, i);
  115.             }
  116.         }
  117.     }
  118.     putchar('\n');
  119. }
  120. void depthvisit(graph *ch, ElemType nn, ElemType n)
  121. {
  122.     printf("下面进行图的深度优先遍历\n");
  123.     int node = nn, j = 1, top = 0, found;
  124.     ch->v[nn] = 1;
  125.     ch->stack[top++] = nn;
  126.     printf("%c", 'A' + nn - 1);

  127.     while (top > 0)
  128.     {
  129.         found = 0;
  130.         while (j <= n)
  131.         {
  132.             if (ch->p[node][j] == 1 && ch->v[j] == 0)
  133.             {
  134.                 ch->v[j] = 1;
  135.                 ch->stack[top++] = j;
  136.                 printf("->%c", 'A' + j - 1);
  137.                 node = j;
  138.                 found = 1;
  139.                 break;
  140.             }
  141.             j++;
  142.         }
  143.         j = 1;
  144.         if (!found)
  145.         {
  146.             top--;
  147.             if (top > 0)
  148.             {
  149.                 node = ch->stack[top - 1];
  150.                 j = ch->stack[top];
  151.             }
  152.         }
  153.     }
  154.     putchar('\n');
  155. }

  156. void input(int *n, int *nn, int *option)
  157. {
  158.     while (1)
  159.     {
  160.         printf("下面将进行图的遍历,请选择深度优先遍历(输入0)或广度优先遍历(输入1):");
  161.         scanf("%d", &(*option));
  162.         if (*option == 0 || *option == 1)
  163.         {
  164.             break;
  165.         }
  166.         else
  167.         {
  168.             printf("您的输入有误!\n\n");
  169.         }
  170.     }
  171.     do
  172.     {
  173.         printf("请输入结点数:");
  174.         scanf("%d", &(*n));

  175.         if (*n <= 0)
  176.         {
  177.             printf("结点数不得小于等于0!\n");
  178.         }
  179.     } while (*n <= 0);
  180.     do
  181.     {
  182.         printf("请选择从哪个结点开始遍历:");
  183.         scanf("%d", &(*nn));

  184.         if (*nn < 1 || *nn > *n)
  185.         {
  186.             printf("您的输入不正确!\n");
  187.         }
  188.     } while (*nn < 1 || *nn > *n);
  189. }
  190. void freeG(graph *ch, int n)
  191. {
  192.     Queue *current = ch->Qhead;
  193.     Queue *next;
  194.     while (current != NULL)
  195.     {
  196.         next = current->Qnode;
  197.         free(current);
  198.         current = next;
  199.     }
  200.     for (int i = 0; i <= n; i++)
  201.     {
  202.         free(ch->p[i]);
  203.     }
  204.     free(ch->p);
  205.     free(ch->v);
  206.     free(ch->stack);
  207. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-12 20:57:09 | 显示全部楼层
人造人 发表于 2023-12-12 17:46
没看懂visit函数
说一下思路

我给你说一下最新的visit的思路
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-12 21:07:15 | 显示全部楼层
本帖最后由 1613551 于 2023-12-12 21:08 编辑
人造人 发表于 2023-12-12 17:46
没看懂visit函数
说一下思路


具体思路就是,n是结点总数,nn是你想从哪个结点开始遍历
v是一个数组,用来记录这个结点有没有被访问过
stack是一个栈,被访问过的元素就入栈
至于那个printf就是把原本的数字1以字母A的形式输出

接下来就是循环,循环的条件是栈里面有结点
found是用来记录在node行里面是否有一条通路是连到另一个结点的,且这个结点没有被访问过。那么条件才成立

进入if以后,把这个结点放进去v数组,说明它也被访问过了,然后也入栈,也就是入stack,然后把fount置为1,就不会进入下一个if

然后第二个if就是你node行里面没有一条通路是连到另一个结点的,那么就开始出栈,也就是回溯。

第一个if里面的条件就是当你当你这个结点里面有这样一条路和其他结点

  1. void depthvisit(graph *ch, ElemType nn, ElemType n)
  2. {
  3.     printf("下面进行图的深度优先遍历\n");
  4.     int node = nn, j = 1, top = 0, found;
  5.     ch->v[nn] = 1;
  6.     ch->stack[top++] = nn;
  7.     printf("%c", 'A' + nn - 1);

  8.     while (top > 0)
  9.     {
  10.         found = 0;
  11.         while (j <= n)
  12.         {
  13.             if (ch->p[node][j] == 1 && ch->v[j] == 0)
  14.             {
  15.                 ch->v[j] = 1;
  16.                 ch->stack[top++] = j;
  17.                 printf("->%c", 'A' + j - 1);
  18.                 node = j;
  19.                 found = 1;
  20.                 break;
  21.             }
  22.             j++;
  23.         }
  24.         j = 1;
  25.         if (!found)
  26.         {
  27.             top--;
  28.             if (top > 0)
  29.             {
  30.                 node = ch->stack[top - 1];
  31.                 j = ch->stack[top];
  32.             }
  33.         }
  34.     }
  35.     putchar('\n');
  36. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-12 21:30:34 | 显示全部楼层
1613551 发表于 2023-12-12 21:07
具体思路就是,n是结点总数,nn是你想从哪个结点开始遍历
v是一个数组,用来记录这个结点有没有被访问 ...

没看懂
stack是一个栈,被访问过的元素就入栈
为什么要入栈?

是不是我下面这个代码的效果?

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>

  5. typedef int ElemType;

  6. typedef struct {
  7.     ElemType **p; // 邻接表矩阵
  8.     size_t n;
  9.     bool *flag;
  10. } graph;

  11. void Initialization(graph *ch, size_t n) {
  12.     ch->p = malloc(sizeof(ElemType *) * n);
  13.     for(int i = 0; i < n; i++) {
  14.         ch->p[i] = malloc(sizeof(ElemType) * n);
  15.     }
  16.     ch->flag = malloc(sizeof(bool) * n);
  17.     ch->n = n;
  18. }

  19. void graph_deinit(graph *graph) {
  20.     for(size_t i = 0; i < graph->n; ++i) free(graph->p[i]);
  21.     free(graph->p);
  22.     free(graph->flag);
  23. }

  24. void create(graph *ch) {
  25.     printf("请输入邻接表矩阵\n");
  26.     for(int i = 0; i < ch->n; i++) {
  27.         for(int j = 0; j < ch->n; j++) {
  28.             scanf("%d", &ch->p[i][j]);
  29.         }
  30.     }
  31. }

  32. void visit_sub(graph *ch, ElemType n) {
  33.     if(ch->flag[n]) return;
  34.     ch->flag[n] = true;
  35.     printf("visit: %d\n", n);
  36.     for(size_t i = 0; i < ch->n; ++i) {
  37.         if(ch->p[n][i]) visit_sub(ch, i);
  38.     }
  39. }

  40. void visit(graph *ch, ElemType n) {
  41.     memset(ch->flag, false, sizeof(bool) * ch->n);
  42.     visit_sub(ch, n);
  43. }

  44. int main(void) {
  45.     unsigned int n, nn;
  46.     graph p;
  47.     printf("请输入结点数:");
  48.     scanf("%u", &n);
  49.     Initialization(&p, n);
  50.     create(&p);
  51.     do {
  52.         printf("请选择从哪个结点开始遍历:");
  53.         scanf("%d", &nn);
  54.         if(nn > n) printf("您的输入不正确!\n");
  55.     } while(nn > n);
  56.     visit(&p, nn - 1);
  57.     graph_deinit(&p);
  58.     return 0;
  59. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-12 21:33:18 | 显示全部楼层
1613551 发表于 2023-12-12 21:07
具体思路就是,n是结点总数,nn是你想从哪个结点开始遍历
v是一个数组,用来记录这个结点有没有被访问 ...

我好像明白了,我那个是递归的版本,你是要非递归的版本
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-12 21:39:49 | 显示全部楼层
人造人 发表于 2023-12-12 21:30
没看懂
stack是一个栈,被访问过的元素就入栈
为什么要入栈?

入栈才能回溯呀,就类似于递归,被访问过的结点入栈,比如你有三个结点
邻接矩阵是:
0 1 0
0 0 1
0 1 0
从第一个结点开始遍历,访问第一行,这时候第一个结点入栈,然后它和第二个结点之间有通路,所以第二个结点入栈,这时候开始访问第二行,然后它和第三个结点之间有通路,所以第三个结点入栈,这时候开始访问第三行。第三行的第二个元素已经访问过了,所以不会入栈,这时候第三行的所有元素都访问了一遍,循环结束,开始弹栈,又从第二行开始遍历,第二行也没有元素没访问过了,然后再弹栈,就回到第一行。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-12 21:40:26 | 显示全部楼层
人造人 发表于 2023-12-12 21:30
没看懂
stack是一个栈,被访问过的元素就入栈
为什么要入栈?

你那个代码我运行不了啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-12 21:40:58 | 显示全部楼层
1613551 发表于 2023-12-12 21:40
你那个代码我运行不了啊

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-12 21:43:35 | 显示全部楼层
人造人 发表于 2023-12-12 21:30
没看懂
stack是一个栈,被访问过的元素就入栈
为什么要入栈?

而且我看不懂你那些函数
1702388578668.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-12 21:45:44 | 显示全部楼层
1613551 发表于 2023-12-12 21:43
而且我看不懂你那些函数

你用的什么编译器?
这看起来你用的C++的编译器
这是C语言代码,用C++编译器编译C语言代码,有问题很正常
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-12 21:46:42 | 显示全部楼层
人造人 发表于 2023-12-12 21:45
你用的什么编译器?
这看起来你用的C++的编译器
这是C语言代码,用C++编译器编译C语言代码,有问题很正 ...

我用的vscode,我一直都写的c程序呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-29 00:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表