Jump to content

Problemas em remover nomes em lista ligada


Recommended Posts

Posted (edited)

Boas tardes ppl,

Estou com um dilema num projecto. Este probelma consite em remover elementos numa lista ligada.

Por Ex:

ze

luisa

andre

quero remover a luisa.

como que faco. ja tentei usar um cilco for mas nao funciona

/*.......*/

void remover(PPNO cabeca, PNO rem) {
PNO *temp;
if (*cabeca != NULL) {
	temp = *cabeca;
	*cabeca = (*cabeca)->prox;
}
free(temp);
}

/*.......*/

int main(int argc, char** argv) {
PNO espec = NULL, medico = NULL, utente = NULL, consulta = NULL;
PPACIENTE p;
PMEDICO m;
PESPECIALIDADE e;
/*.....*/
			printf("\nNome: ");
			scanf(" %[^\n]", &nome);
			remover(&medico, pesquisa(medico, compnomeMedico, nome));
}

/*.......*/

obrigado e comprimentos

Edited by pmg
GeSHi
Posted

Imagina que tens a lista ligada com os nomes Jose, Ricardo e Nuno e queres apagar o Ricardo.

1) --> Jose --> Ricardo --> Nuno -->


2) --> Jose --\ Ricardo -/> Nuno -->
              \--------/


3) --> Jose --\          /> Nuno -->
              \--------/

1) posicao inicial

2) Tens que pegar no link do Jose e aponta-lo para onde aponta o link do Ricardo (para o Nuno)

3) liberta o Ricardo

ou seja, para apagar o Ricardo tens que primeiro mexer no Jose e só a seguir é que fazes o free().

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

Deixo um exemplo de um método de um projecto que fiz à tempos, pode ser que dê jeito. Mais explicitamente o código que utilizei para eliminar companhias aéreas de uma lista. Pedia o nome a eliminar, verificava se este existia, e caso existisse pedia a confirmação da sua eliminação.

void eliminar_companhias_aereas()
{
   char resp;
   int posicao;
   int i, j, a, var =0;
   int verdade = FALSE;
   char nome_companhia_a_eliminar[25];
   int total;

   system("CLS");
   if(n_companhias == 0)
   {
    mensagem("Nao existem companhias para serem eliminadas.\n");
    getch();
   }
   else
   {
    puts("Insira o nome da companhia a ser eliminada: ");
    scanf("%s", &nome_companhia_a_eliminar);
    for (i=0; i <n_companhias; i++)
    {
	    if (stricmp(companhias[i].nome, nome_companhia_a_eliminar)==0)
	    {
		    posicao = i;
		    verdade=TRUE;
	    }
    }
    if(verdade==FALSE)
    {
	    mensagem("A companhia que pesquisou nao existe!");
	    getch();
    }
    else
    {	   printf("\nID: %d\nNome: %s\n", companhias[posicao].codigo, companhias[posicao].nome);
		    getch();
		    resp = respostaSN("\nTem a certeza que quer eliminar a companhia? <S/N>\n");
		    if(resp == 's' || resp == 'S')
		    {
			    for (i = posicao; i <(n_companhias-1); i++)
			    {
				    companhias[i] = companhias[i+1];
			    }
			    n_companhias--;
			    mensagem ("Companhia eliminada com sucesso.\n");
		    }
		    else
		    {
			    mensagem("Companhia nao eliminada");
		    }
	    }

	    }
    }
   }
}
Posted (edited)

Tens 2 modelos:

O recursivo, que pode custar mais a entender para quem está habituado a programação imperativa, mas que pode ser mais fácil e simples de programar e de ler, se entenderes bem o que estás a fazer.

Ou o imperativo, um bocado mais complexo, mas mais fácil de entender para quem não entende bem a recursividade.

Recursivo:

lista remove_lista(lista)
se lista = null
retorna null
senão se (lista é o nodo a remover)
retorna o lista->proximo
senao
lista->proximo = remove_lista(lista->proximo)
retorna lista;

A função devolve-te a nova lista já sem o elemento (faltam aí os frees, lógico).

No caso imperativo, tens sempre de ter em atenção as extremidades.

Se o primeiro nodo é o nodo a remover, a tua lista passa a ser o nodo seguinte.
Senão olhas sempre para o seguinte, enquanto houver.
listatemp=lista;
enquanto (listatemp->proximo != null && listatemp->proximo não for o nodo a remover)
 listatemp=listatemp->proximo
Se listatemp->proximo = null
 não encontrou o nodo
senao listatemp->proximo = listatemp->proximo->proximo (usar variavel temporaria para fazer o free ao nodo removido)

Podem existir solução mais elegantes, mas isto é o que eu costumo fazer. Testa sempre as remoções nas extremidades que costumam ser os casos mais complicados.

Edited by Flinger
Posted (edited)

O recursivo, que pode custar mais a entender para quem está habituado a programação imperativa, mas que pode ser mais fácil e simples de programar e de ler, se entenderes bem o que estás a fazer.

Só uma nota, durante o teu post falas sempre em programação imperativa. Não quererás dizer antes programação iterativa?

Edited by AriOps

Daniel Correia

Posted (edited)

nop ... imperativa

Imperativas são algumas linguagens como o C, Java, etc (http://pt.wikipedia....ação_imperativa) em contraste com as linguagens de programação funcional.

Neste caso falam-se de algoritmos e, pelo que sei, só tens dois tipos de algoritmos em linguagens imperativas (já que falamos de C): Iterativos ou Recursivos.

Iterativo tem a ver com a repetição das acções em blocos de loop comuns (ver http://pt.wikipedia....g/wiki/Iteração).

Recursivo está relacionado com a manipulação das chamadas a funções principalmente para tornar o código mais simples em determinados algoritmos (ver http://pt.wikipedia....i/Recursividade).

Acho que não me enganei, mas podes argumentar 🙂

PS: Ele estava a falar do tipo do algoritmo, não era do tipo da linguagem.

Edited by AriOps

Daniel Correia

Posted

PS: Ele estava a falar do tipo do algoritmo, não era do tipo da linguagem.

não é tipo de linguagem ... é paradigma de programação.

e sim ... ele quis dizer imperativa.

o paradigma de programação imperativa é normalmente resolvido pelo modelo iterativo porque é a resolução é mais directa

o paradigma funcional, terá uma abordagem recursiva

assim como outros paradigmas nem contemplam este tipo de abordagem ao problema.

IRC : sim, é algo que ainda existe >> #p@p
Posted

Mas tendo em conta que estamos na secção de C (logo, paradigma imperativo) e analisando os algoritmos que ele inseriu... podes ver que nestas frases:

Ou o imperativo, um bocado mais complexo, mas mais fácil de entender para quem não entende bem a recursividade.

e

No caso imperativo, tens sempre de ter em atenção as extremidades.

Ele estava mesmo a falar da abordagem iterativa, e não do paradigma.

Daniel Correia

Posted

Eh pa, no meu tempo só falavamos dos paradigmas de programação. Fiz o algoritmo num pseudo-código porque também não queria dar o exercício todo de mão beijada. Por isso admito que possa ter uma designação mais correcta. Nesse ponto admito a minha ignorância.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.