【问题标题】:Understanding recursive function in linked-list C了解链表 C 中的递归函数
【发布时间】:2018-12-03 20:38:40
【问题描述】:

假设我编写了一个模拟多米诺骨牌游戏的程序,所以我想通过以下方式定义一个结构体:

typedef struct nodo { 
    int casella1;
    int casella2;
    struct nodo *next;
} Tessera;
typedef Tessera *Lista;

然后在以随意顺序进行一些输入后,当输入超出范围 0 casella2 应该始终由 ->next->casella1 中的相同数字后接,使用递归函数,如下所示:

void legale(Lista *head) {

    Lista aux,aus = *head;

    if(aus->next == NULL) {
      return;
    }

    else if(aus->casella2 == aus->next->casella1)   {
      legale(&(aus->next));
    }
    else {
      aux = aus->next;
      aus->next = aus->next->next;  
      free(aux);
    }
}

但是例如序列“ 1 2, 2 3, 3 4, 4 5, 5 4, 6 2, 7”给出“1 2, 2 3, 3 4, 4 5,6 2” 所以它没有t 应该删除 6,2。

我觉得我删除指针的方式是对的,那为什么函数不对呢?

代码如下:

#include<stdio.h>
#include<stdlib.h>
typedef struct nodo { 
    int casella1;
    int casella2;
    struct nodo *next;
    }Tessera;
typedef Tessera *Lista;

void stampa(Lista *head) {

    Lista ausil = *head;

    while(ausil != NULL) {
    printf("%d\t%d\n",ausil->casella1,ausil->casella2);
    ausil = ausil->next;
    }
}

void legale(Lista *head) {

    Lista aux,aus = *head;

    if(aus->next == NULL) {
    return;
}

    else if(aus->casella2 == aus->next->casella1)   {
    legale(&(aus->next));
}
    else {
    aux = aus->next;
    aus->next = aus->next->next;    
    free(aux);
}


}

void write (Lista *head) {
    Lista corr,aux,aus;
    int x,y;
    scanf("%d%d",&x,&y);
    aus = *head;

    while((x >= 0 && x <= 6) && (y >= 0 && y <= 6)) {

    if(aus == NULL) {

    aus = malloc(sizeof(Tessera));
    aus->casella1 = x;  
    aus->casella2 = y;
    aus->next = NULL;
    *head = aus;
}
    else {
    aux = *head;

    corr = malloc(sizeof(Tessera));
    corr->casella1 = x;
    corr->casella2 = y;
    corr->next = aux;
    *head = corr;
}
    scanf("%d%d",&x,&y);
    }

}

int main() {
    Lista Lista1 = NULL;
    write(&Lista1);
    legale(&Lista1);
    stampa(&Lista1);
return 0;
}

【问题讨论】:

    标签: c function recursion struct linked-list


    【解决方案1】:

    删除重复项后,您至少错过了一次递归调用,

    else {
      aux = aus->next;
      aus->next = aus->next->next;  
      free(aux);
    }
    

    如果您不递归,您将在第一次删除后停止。

    同样谨慎起见,在检查是否aus-&gt;next == NULL 之前,您应该检查是否aus == NULL,这样如果您传递一个空列表,它就不会中断。


    编辑

    当您阅读链表时,您正在反向构建链表。

    您将每一对插入到头部,所以最后您的序列会倒退。阅读清单后打印出清单以确保一切正常,这总是一个好主意;)

    【讨论】:

    • 我同意,但它至少应该删除最后一个,所以如果只有一个是错误的,那么顺序应该是正确的
    • 确实如此。我不明白你的例子,你写道:"1 2, 2 3, 3 4, 4 5, 5 4, 6 2, 7" 给了"1 2, 2 3, 3 4, 4 5,6 2"。在这里它确实删除了5 4(它不应该有)。 7 本身又是什么?最好提供一个可编译、可测试的最小示例
    • 它不应该删除 5 4,它应该删除 6 2,7 只是为了停止序列,如所写“当数字超出范围 0
    猜你喜欢
    • 2015-11-13
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 2021-03-07
    相关资源
    最近更新 更多