Good evening,
I am trying to solve an issue that asked to remove students whose CR is less than 5. My biggest problem is to remove the first node (first student) from a double-chained list when there is only one node. I just gave free on the node containing the CR with value less than 5, and made the head of the list point to NULL, which would be the address of the successor node to which it will be deleted, nothing too much. The result is that at the time of printing the list, the node remained intact, but with random values after the free () call. Follow the print and source code for better analysis.
I'm counting on everyone's help!
#include<stdio.h>#include<stdlib.h>typedefstruct{longmatricula;charnome[51];floatCR;}DADOS_ALUNO;typedefstruct{DADOS_ALUNOdados;//Dadosdoalunovoid*pProximoAluno;//Ponteiroparaopróximoalunovoid*pAlunoAnterior;//Ponteiroparaalunoanterior}ELEMENTO;ELEMENTO*criaLista(){returnNULL;}ELEMENTO*cadastraAlunos(ELEMENTO*lista,DADOS_ALUNOnovo_aluno){ELEMENTO*novo=(ELEMENTO*)malloc(sizeof(ELEMENTO));//InicialmenteosponteirosiniefimapontamparaNULLELEMENTO*ini=lista;ELEMENTO*fim=lista;if(novo==NULL){printf("Memoria insuficiente\n");
exit(1);
} else if(lista == NULL){ //Se a lista estiver vazia, insere o primeiro nó
novo->dados = novo_aluno;
novo->pProximoAluno = fim;
novo->pAlunoAnterior = ini;
fim = ini = novo;
return ini;
} else { //Caso a lista tenha pelo menos um nó
novo->dados = novo_aluno;
novo->pProximoAluno = fim;
novo->pAlunoAnterior = NULL;
fim->pAlunoAnterior = novo;
ini = novo;
return ini;
}
}
//a)Retornar a quantidade de alunos com coeficiente de rendimento maior ou igual a 7.
int numAlunosCrAlto(ELEMENTO* pLista){
int quantidade = 0;
ELEMENTO* p = pLista; //Ponteiro que aponta para o início da lista para percorrê-lo
if(pLista == NULL){
printf("Lista vazia\n");
exit(1);
} else {
while(p != NULL){
if(p->dados.CR >= 7){
quantidade++;
}
p = p->pProximoAluno;
}
return quantidade;
}
}
void imprimeAluno(ELEMENTO* lista){
ELEMENTO* p = lista;
if(lista == NULL){
printf("Lista vazia\n");
exit(1);
} else {
for(; p != NULL; p = p->pProximoAluno){
printf("Matricula: %ld - Nome: %s - CR: %.2f\n", p->dados.matricula, p->dados.nome, p->dados.CR);
}
printf("\n\n");
}
}
//b)Excluir da lista todos os alunos com coeficiente de rendimento menor que 5.
void excluirAlunosCrBaixo(ELEMENTO* pLista){
ELEMENTO* p = pLista; //Ponteiro que aponta para o primeiro nó da lista para percorrê-la
ELEMENTO* ant = NULL; //Ponteiro para guardar o nó antecessor ao que será excluído
if(pLista == NULL){
printf("Lista vazia\n");
exit(1);
} else {
while(p != NULL){
if(p->dados.CR < 5 && p->pAlunoAnterior == NULL){ //Se for primeiro da lista
if(p->pProximoAluno == NULL){ //Se não houver mais elementos na lista, a mesma fica vazia
ant = p; /*Usando o ponteiro ant para apontar ao p e chamar o free() sobre ele para
não perder a referência de p, pois este será utilizado para percorrer a lista*/
pLista = ant->pProximoAluno; //A cabeça da lista aponta para NULL, indicando que está vazia
free(ant);
} else { //Caso ainda exista mais elementos na lista, o segundo elemento passa a ser o primeiro
ant = p;
p = p->pProximoAluno;
free(ant);
p->pAlunoAnterior = NULL;
}
} else if(p->dados.CR < 5 && p->pAlunoAnterior != NULL && p->pProximoAluno != NULL){ //Se o elemento estiver no meio da lista
ELEMENTO* aux; //Ponteiro que irá apontar para o nó antecessor ao nó que será excluído
ant = p;
aux = ant->pAlunoAnterior;
p = p->pProximoAluno;
p->pAlunoAnterior = aux;
aux->pProximoAluno = p;
free(ant);
} else if(p->dados.CR < 5 && p->pProximoAluno == NULL){ //Se for o último da lista
ant = p->pAlunoAnterior;
ant->pProximoAluno = NULL;
free(p);
}
p = p->pProximoAluno;
}
}
}
int main(int argc, char *argv[]) {
ELEMENTO* Lista = (ELEMENTO*)malloc(sizeof(ELEMENTO));
if(Lista == NULL){
printf("Memoria insuficiente\n");
exit(1);
} else {
Lista = criaLista();
// DADOS_ALUNO a1 = {201311, "Teste 01", 8.5};
// DADOS_ALUNO a2 = {201412, "Teste 02", 6.3};
// DADOS_ALUNO a3 = {201211, "Teste 03", 6.2};
DADOS_ALUNO a4 = {201511, "Teste 04", 1.0};
// Lista = cadastraAlunos(Lista, a1);
// Lista = cadastraAlunos(Lista, a2);
// Lista = cadastraAlunos(Lista, a3);
Lista = cadastraAlunos(Lista, a4);
imprimeAluno(Lista);
excluirAlunosCrBaixo(Lista);
imprimeAluno(Lista);
printf("Total de alunos com CR maior ou igual a 7: %d", numAlunosCrAlto(Lista));
}
return 0;
}