了解链表C中的递归函数

时间:2018-12-03 20:38:40

标签: c function recursion struct linked-list

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

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

然后在输入了0 <= x <= 6范围外的数字时以随意的顺序结束一些输入之后,我想删除不遵守多米诺规则的可能重复项。使用递归函数,数字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;
}

1 个答案:

答案 0 :(得分:1)

删除重复项后,您至少缺少递归调用

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

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

此外,为预防起见,在检查aus->next == NULL之前是否应该检查aus == NULL,以便在将其传递为空列表时也不会中断。


编辑

您正在阅读时向后构造链表。

将每对插入头部,因此最后将序列向后移动。在阅读清单后将其打印出来以确保确定是一个好主意;)