c - C中递归地从链表中删除节点

标签 c pointers linked-list

我是 C 语言新手,但我仍然很难理解指针和喜欢列表的工作原理,因此我对所有这些都遇到了一些问题。

我正在尝试从链接列表中删除一个节点,并且我正在使用 this link 上的示例,但我无法让它工作。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct voos
{
int numeroVoo;
char ciaAerea[20];
char modeloAeronave[20];
char origem[20];
char destino[20];
int qtdeTotalAssentos;
int qtdeAssentosOcupados;
struct voos *proximo;
} *cadastroVoo;

int cont = 0; //Contador temporario para contar numero de assentos ocupados
void addVoo (cadastroVoo *local) //Add item to list
{
cadastroVoo novo;
novo = (cadastroVoo) malloc(sizeof(struct voos));
char temp[20];
if (novo != NULL)
{
    printf("Informe o numero do voo: \n");
    scanf("%d", &novo->numeroVoo);

    printf("Informe a cia aerea: \n");
    fflush(stdin);
    gets(temp);
    strcpy(novo->ciaAerea, temp);

    printf("Informe o modelo da aeronave: \n");
    fflush(stdin);
    gets(temp);
    strcpy(novo->modeloAeronave, temp);

    printf("Informe a origem do voo: \n");
    fflush(stdin);
    gets(temp);
    strcpy(novo->origem, temp);

    printf("Informe o destino do voo: \n");
    fflush(stdin);
    gets(temp);
    strcpy(novo->destino, temp);

    cont++;
    novo->qtdeAssentosOcupados = cont;

    novo->qtdeTotalAssentos = 50;

    novo->proximo = *local;
    *local = novo;
}
}

void listarVoos(cadastroVoo local) //prints list
{
printf("Imprimindo lista atualizada: \n\n\n");
while (local != NULL)
{
    printf("Numero voo: %d\n", local->numeroVoo);
    printf("Cia Aerea: %s\n", local->ciaAerea);
    printf("Modelo aeronave: %s\n", local->modeloAeronave);
    printf("Origem: %s\n", local->origem);
    printf("Destino: %s\n", local->destino);
    printf("Quantidade total de assentos: %d\n", local->qtdeTotalAssentos);
    printf("Quantidade de assentos ocupados: %d\n", local->qtdeAssentosOcupados);
    printf("\n");
    local = local->proximo;
}
}

cadastroVoo *cancelarPassagem(cadastroVoo *local, int numVoo) //deletes item from list
{
// See if we are at end of list.
if (local == NULL) return NULL;

// Check to see if current node is one to be deleted.
if (local->numeroVoo == numVoo)
{
    cadastroVoo *tempNextP;

    tempNextP = local->proximo;

    free(local);

    return tempNextP;
}

// Check the rest of the list, fixing the next pointer in case the next node is the one removed.
local->proximo = cancelarPassagem(local->proximo, numVoo);

//Return the pointer to where we were called from.  Since we did not remove this node it will be the same.
return local;
}

int main()
{
cadastroVoo cadastro = NULL;
char op;
while(op != 'f')
{
    printf("Escolha a opcao:\n");
    printf("a - Incluir voos:\n");
    printf("b - Listar voos:\n");
    printf("c - Reservar assento em um voo:\n");
    printf("d - Cancelar voo:\n");
    printf("e - Cancelar passagem:\n");
    printf("f - Sair:\n");
    op = getche();
    printf("\n");
    switch(op)
    {
    case 'a':
        {
            printf("Incluir voo. \n");
            addVoo(&cadastro);
            printf("Voo incluso.\n");
            break;
        }
    case 'b':
        {
            listarVoos(cadastro);
            break;
        }
    case 'c':
        {
            printf("Reservar assento em um voo. \n");
            addVoo(&cadastro);
            printf("Assento reservado.\n");
            break;
        }
    case 'd':
        {
            /**
            *while (cancelarVoo != NULL) cancelarVoo()
            */
            break;
        }
    case 'e':
        {
            int numVoo;
            printf("Informe o numero do voo que deseja cancelar a passagem: \n");
            scanf("%d", &numVoo);
            cancelarPassagem(&cadastro, numVoo);
            printf("Passagem cancelada");
            break;
        }
    case 'f': break;
    default:
        {
            printf("Opcao invalida.");
            break;
        }
    }
}

return 0;
}

在方法声明中,如果我通过:

cadastroVoo *cancelarPassagem(cadastroVoo *local, int numVoo)

我收到错误:请求成员“numeroVoo”不是结构或 union

但是如果我通过了

cadastroVoo *cancelarPassagem(cadastroVoo local, int numVoo)

它会运行,但是当我选择调用此方法的选项时,我会在 Windows 上收到它停止工作的消息。

有人知道可能出了什么问题吗?

提前致谢。

最佳答案

您可能没有传递指向该函数的指针。我在这里尝试了你的代码,逻辑工作正常。

#include <stdio.h>
typedef struct cadastroVoo {
    struct cadastroVoo *proximo;
    int numero;
} CadastroVoo;

CadastroVoo *cancelarPassagem(CadastroVoo *local, int num);

void inserir(CadastroVoo *cabeca, int num) {
    CadastroVoo *p = (CadastroVoo *) malloc(sizeof(CadastroVoo)); 
    p->proximo = cabeca->proximo;
    p->numero = num;
    cabeca->proximo = p;
}

CadastroVoo *cancelarPassagem(CadastroVoo *local, int num) {
    if (local == NULL) return NULL;
    printf("> %d\n", local->numero);
    printf("> %p\n", local->proximo);
    if (local->numero == num) {
        CadastroVoo *proximo = local->proximo;
        free(local);
        return proximo;
    } 
    local->proximo = cancelarPassagem(local->proximo, num);
    return local;
}   

int main() {
    CadastroVoo *cabeca = (CadastroVoo *) malloc(sizeof(CadastroVoo)); 
    cabeca->proximo = NULL;

    inserir(cabeca, 10);
    inserir(cabeca, 20);
    inserir(cabeca, 30);
    inserir(cabeca, 40);
    inserir(cabeca, 50);

    cancelarPassagem(cabeca->proximo, 20);

    CadastroVoo *p = cabeca->proximo;
    while (p != NULL) {
        printf("%d\n", p->numero);
        p = p->proximo;
    }
}

关于c - C中递归地从链表中删除节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40596860/

相关文章:

c - 在声明 VLA 的同一序列点中启动 VLA 的大小部分是否有效?

c++ - 在循环中将指针设置为 int 值

c++ - 通过指针比较聚合类型的成员值

c - 将节点插入到链表的尾部

c - 标记化字符串循环内存错误

c - 为什么内存地址在一个地方上升而在另一个地方下降?

c++ - 从 ‘const char*’ 到 ‘char*’ [-fpermissive] 的无效转换

c++ - 使用 offsetof() 从成员变量中获取所有者对象

c++ - 遍历指向类的指针 vector

algorithm - 两次遍历链表遍历的时间复杂度