|
60鱼币
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- typedef int ElemType;
- typedef struct graph
- {
- ElemType *v; // 通过入栈的方式判断结点是否有被遍历
- ElemType **p; // 邻接表矩阵
- ElemType *stack;
- } graph;
- void Initialization(graph *ch, ElemType n)
- {
- ch->p = (ElemType **)malloc(sizeof(ElemType *) * pow((n + 1), 2));
- for (int i = 1; i <= n; i++)
- {
- ch->p[i] = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
- }
- ch->v = (ElemType *)malloc(sizeof(ElemType) * (n + 1));
- ch->stack = (ElemType *)malloc(sizeof(ElemType) * n);
- }
- void create(graph *ch, ElemType n)
- {
- printf("请输入邻接表矩阵\n");
- for (int i = 1; i <= n; i++)
- {
- for (int j = 1; j <= n; j++)
- {
- scanf("%d", &(ch->p[i][j]));
- }
- }
- }
- void visit(graph *ch, ElemType nn, ElemType n)
- {
- int node = nn, j = 1, top = 0;
- ch->v[nn] = 1;
- ch->stack[top++] = nn;
- printf("%d", nn);
- while (1)
- {
- if (ch->p[node][j] == 1 && ch->v[j] == 0)
- {
- ch->v[j] = 1;
- ch->stack[top++] = j;
- printf("->%d", j);
- node = j;
- j = 1;
- };
- if (j == n + 1)
- {
- if (ch->stack[top] == nn)
- {
- break;
- }
- ch->stack[top--] = 0;
- node = ch->stack[top];
- j = 1;
- }
- j++;
- }
- }
- int main(void)
- {
- int n, nn;
- graph p;
- do
- {
- printf("请输入结点数:");
- scanf("%d", &n);
- if (n <= 0)
- {
- printf("结点数不得小于等于0!\n");
- }
- } while (n <= 0);
- Initialization(&p, n);
- create(&p, n);
- do
- {
- printf("请选择从哪个结点开始遍历:");
- scanf("%d", &nn);
- if (nn < 0 || nn > n)
- {
- printf("您的输入不正确!\n");
- }
- } while (nn < 0 || nn > n);
- visit(&p, nn, n);
- system("pause");
- return 0;
- }
复制代码
嗯,对于图来说,确实需要一个vector来标记已经访问过的节点,不然会死循环,因为有多条路径
改成这样,非递归的版本
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <string.h>
- typedef int ElemType;
- typedef struct {
- ElemType e;
- size_t status;
- } stack_elem_t;
- typedef struct {
- stack_elem_t *data;
- size_t size, top;
- } stack_t;
- stack_t *stack_init(void) {
- stack_t *stack = malloc(sizeof(*stack));
- stack->data = NULL;
- stack->size = stack->top = 0;
- return stack;
- }
- void stack_deinit(stack_t *stack) {
- free(stack->data);
- free(stack);
- }
- size_t stack_size(const stack_t *stack) {
- return stack->top;
- }
- bool stack_empty(const stack_t *stack) {
- return stack_size(stack) == 0;
- }
- void stack_push(stack_t *stack, stack_elem_t e) {
- if(stack->top == stack->size)
- stack->data = realloc(stack->data, sizeof(stack_elem_t) * (stack->size += 10));
- stack->data[stack->top++] = e;
- }
- void stack_pop(stack_t *stack) {
- if(stack_empty(stack)) return;
- --stack->top;
- }
- stack_elem_t stack_top(const stack_t *stack) {
- if(stack_empty(stack)) abort();
- return stack->data[stack->top - 1];
- }
- typedef ElemType vector_elem_t;
- typedef struct {
- vector_elem_t *data;
- size_t size;
- } vector_t;
- vector_t *vector_init(void) {
- vector_t *vector = malloc(sizeof(*vector));
- vector->data = NULL;
- vector->size = 0;
- return vector;
- }
- void vector_deinit(vector_t *vector) {
- free(vector->data);
- free(vector);
- }
- size_t vector_size(const vector_t *vector) {
- return vector->size;
- }
- size_t vector_empty(const vector_t *vector) {
- return vector_size(vector) == 0;
- }
- void vector_set(vector_t *vector, size_t index, vector_elem_t e) {
- if(index >= vector->size)
- vector->data = realloc(vector->data, sizeof(vector_elem_t) * (vector->size = index + 1));
- vector->data[index] = e;
- }
- vector_elem_t vector_get(const vector_t *vector, size_t index) {
- if(index >= vector->size) abort();
- return vector->data[index];
- }
- void vector_append(vector_t *vector, vector_elem_t e) {
- vector_set(vector, vector_size(vector), e);
- }
- bool vector_find(const vector_t *vector, vector_elem_t e) {
- for(size_t i = 0; i < vector_size(vector); ++i) {
- if(vector_get(vector, i) == e) return true;
- }
- return false;
- }
- typedef struct {
- ElemType **p;
- size_t n;
- } graph;
- void Initialization(graph *ch, size_t n) {
- ch->p = malloc(sizeof(ElemType *) * n);
- for(int i = 0; i < n; i++) {
- ch->p[i] = malloc(sizeof(ElemType) * n);
- }
- ch->n = n;
- }
- void graph_deinit(graph *graph) {
- for(size_t i = 0; i < graph->n; ++i) free(graph->p[i]);
- free(graph->p);
- }
- void create(graph *ch) {
- printf("请输入邻接表矩阵\n");
- for(int i = 0; i < ch->n; i++) {
- for(int j = 0; j < ch->n; j++) {
- scanf("%d", &ch->p[i][j]);
- }
- }
- }
- void visit(graph *ch, ElemType n) {
- stack_t *stack = stack_init();
- vector_t *vector = vector_init();
- stack_elem_t se = {n, 0};
- stack_push(stack, se);
- while(!stack_empty(stack)) {
- se = stack_top(stack);
- switch(se.status) {
- case 0:
- printf("%d\n", se.e);
- stack_pop(stack);
- stack_push(stack, (stack_elem_t){se.e, 1});
- vector_append(vector, se.e);
- for(size_t i = 0; i < ch->n; ++i) {
- if(ch->p[se.e][i] && !vector_find(vector, i)) stack_push(stack, (stack_elem_t){i, 0});
- }
- break;
- case 1:
- stack_pop(stack);
- }
- }
- vector_deinit(vector);
- stack_deinit(stack);
- }
- int main(void) {
- unsigned int n, nn;
- graph p;
- printf("请输入结点数:");
- scanf("%u", &n);
- Initialization(&p, n);
- create(&p);
- do {
- printf("请选择从哪个结点开始遍历:");
- scanf("%d", &nn);
- if(nn > n) printf("您的输入不正确!\n");
- } while(nn > n);
- visit(&p, nn - 1);
- graph_deinit(&p);
- return 0;
- }
复制代码
|
最佳答案
查看完整内容
嗯,对于图来说,确实需要一个vector来标记已经访问过的节点,不然会死循环,因为有多条路径
改成这样,非递归的版本
|