Como remover um nó em uma lista encadeada - Parte IV

แชร์
ฝัง
  • เผยแพร่เมื่อ 19 ธ.ค. 2024

ความคิดเห็น • 17

  • @edsilva7405
    @edsilva7405 2 ปีที่แล้ว

    Salvando a jornada, parabéns pela didática. Obrigado,

  • @joaovictorpereiradeandrade5517
    @joaovictorpereiradeandrade5517 3 ปีที่แล้ว +6

    Cara tu manda muito! Não sei como não tem mais visualizações, sua didática é impecável!

    • @programeseufuturo
      @programeseufuturo  3 ปีที่แล้ว

      Né. Também fico me perguntando isso 😅 😅 😅
      Que bom que ajudou João. Obrigado pelo feedback.

  • @ruantarcisio9670
    @ruantarcisio9670 3 ปีที่แล้ว +3

    Salvou de mais, vi outros vídeos até parar no seu (os outros não desmerecendo) deixavam o assunto mais complicado... Mas você? Nossa fez o bicho papão virar borboleta

    • @programeseufuturo
      @programeseufuturo  3 ปีที่แล้ว

      "fez o bicho papão virar borboleta" 🤣 🤣 🤣 🤣 🤣
      Vou emoldurar essa comparação kkkkkk.
      Obrigado pelo feedback Ruan. Fico feliz em saber que ajudou em vez de complicar rsrs.
      Abraços e bons estudos.

  • @joseartininetto1160
    @joseartininetto1160 3 ปีที่แล้ว +2

    Didática nota 1000!!!!!!!!!!

  • @elvisdemoraisinacio6880
    @elvisdemoraisinacio6880 3 ปีที่แล้ว +2

    Cara sensacional seu vídeo, muito didático mesmo, ajudando muito

    • @programeseufuturo
      @programeseufuturo  3 ปีที่แล้ว

      Obrigado Elvis pelo feedback 🤩.
      Fico feliz em saber que está ajudando.

  • @JoaoPaulo-zv8ry
    @JoaoPaulo-zv8ry 2 ปีที่แล้ว +5

    Galera, segue meu código completo e comentado baseado no que o professor ensinou. Espero que ajude. Uma dica de ouro: só consegui entender essa matéria quando comecei a literalmente desenhar o que estava acontecendo no papel, os nós e como eles se relacionam na lista nos processos de inserir e excluir, acreditem, ajuda muito. Para quem quiser ter essa ideia visual de como representar no papel, deem uma olhada nos vídeos do Pietro, vai ajudar ainda mais. 👇👇👇

    • @JoaoPaulo-zv8ry
      @JoaoPaulo-zv8ry 2 ปีที่แล้ว +3

      #include
      #include
      //Estrutura principal do programa, é o nosso nó contendo o dado e o ponteiro para o próximo nó
      typedef struct no{
      int conteudo;
      struct no *proximo;
      }no;
      //Lista (conjunto de nós)
      typedef struct Lista{
      no *inicio;
      int tamanho;
      }Lista;
      //Inicializa os parâmetros da lista
      void inicializaLista(Lista *lista){
      lista->inicio = NULL;
      lista->tamanho = 0;
      }
      void inserirInicio(int elemento, Lista *lista){
      //Aloca dinamicamente memória para o novo nó
      no *novo = (no*)malloc(sizeof(no));
      //O conteudo do novo nó recebe o elemento a ser adicionado
      novo->conteudo = elemento;
      //novo->proximo aponta para o mesmo local que lista->inicio aponta. No primeiro caso, é NULL,
      //depois o novo->proximo passa a apontar sempre para onde lista->inicio aponta (que será o nó antigo)
      //ou seja, o novo nó passa a apontar para o seu anterior, dessa forma, nós concatenamos os 2 nós,
      //mas sempre colocando o novo nó criado antes na lista, ou seja, no início
      novo->proximo = lista->inicio;
      //O início da lista, que apontava para o nó mais recente (que está no início) passa a apontar para o novo nó
      //formalizando a entrada do novo nó, de fato, no início da lista. Observe que lista->inicio recebe o endereço
      //do novo nó, passando a apontar para o novo nó que agora é o primeiro da lista, já que estamos inserindo no início
      lista->inicio = novo;
      //O tamanho da lista é incrementado
      lista->tamanho++;
      //OBS: note que tanto inserindo no inicío da lista quanto no final, o último nó sempre apontará para NULL
      }
      void inserirFim(int elemento, Lista *lista){
      //Aloca dinamicamente memória para o nó e inicializa os parâmetros dele
      no *novo = (no*)malloc(sizeof(no));
      //O conteudo do novo nó recebe o elemento a ser adicionado
      novo->conteudo = elemento;
      //Se a lista estiver vazia, lista->inicio já recebe o novo nó e já fazemos o primeiro, e por ora, último nó
      //apontar para NULL
      if(lista->inicio == NULL){
      lista->inicio = novo;
      novo->proximo = NULL;
      //Se já houverem elementos na lista, criamos um ponteiro do tipo nó que recebe o início da lista
      //e andamos até o final da lista com o while através do ponteiro criado, quando iterador->proximo for
      //NULL, ou seja, ele aponta para o mesmo local que o ponteiro do último nó aponta, significa que chegamos
      //ao final da lista e o iterador->proximo pode receber o endereço do novo nó criado
      } else {
      no *iterador = lista->inicio;
      while(iterador->proximo != NULL){
      iterador = iterador->proximo;
      }
      //Observe que esse ponteiro consegue alterar os ponteiros dos nós na lista. Aqui ele faz com que o ponteiro
      //do último nó passe a apontar para o endereço do novo nó criado, concatenando os 2. E o ponteiro do
      //último nó, aponta para NULL, como sempre deve acontecer.
      iterador->proximo = novo;
      novo->proximo = NULL;
      }
      //O tamanho da lista é incrementado
      lista->tamanho++;
      //OBS: note que tanto inserindo no inicío da lista quanto no final, o último nó sempre apontará para NULL
      }
      void excluir(int elemento, Lista *lista){
      //Lista vazia já tratada na main()
      //É o caso do primeiro elemento da lista ser o que queremos remover
      if(lista->inicio->conteudo == elemento){
      //noARemover aponta para o mesmo local que lista->inicio, ou seja, o primeiro nó
      no *noARemover = lista->inicio;
      //lista->inicio agora aponta para o mesmo local que o primeiro nó. Se a lista tiver 2 ou mais
      //nós, lista->inicio aponta para o segundo nó, se a lista só tiver um nó, lista->inicio
      //volta a apontar para NULL
      lista->inicio = noARemover->proximo;
      //O nó a ser removido passa a apontar para NULL e é completamente desligado da lista
      noARemover->proximo = NULL;
      free(noARemover);
      //O tamanho da lista é decrementado
      lista->tamanho--;
      printf("
      %d foi removido!
      ", elemento);
      //Se não for o primeiro elemento que queremos remover, vamos para o else
      }else {
      //Criamos um nó de iteração no loop começando do início da lista
      no *iterador = lista->inicio;
      //O programa só sairá do loop se o conteudo do iterador->proximo for o mesmo que o elemento
      //ou se o iterador->proximo apontar para NULL, o que significa que o usuário provavelmente tentou
      //remover um elemento que não existe (ou não está cadastrado) na lista
      while(iterador->proximo != NULL && iterador->proximo->conteudo != elemento){
      //Se o elemento não for o que estamos procurando no nó, andamos com o interador na lista
      //e continuamos as comparações. Note que o iterador sempre estará apontando para o nó
      //anterior ao que queremos remover
      iterador = iterador->proximo;
      }
      //Se esse if é verdadeiro, significa que o iterador está apontando para o último nó e o elemento
      //digitado não existe na lista
      if(iterador->proximo == NULL){
      printf("Provavalmente, voce digitou um numero que nao existe na lista. Tente novamente.
      ");
      }else {
      //Criamos um outro nó que, além de apontar para o nó a ser removido, irá funcionar como Backup
      //do *proximo do nó anterior que iremos remover porque o objetivo é ligar o *proximo do nó anterior
      //com o *proximo do nó a ser removido, ou seja, o nó anterior ao que será removido passará a apontar
      //para o mesmo local que o que o nó a ser removido aponta, ligando o nó anterior com o próximo nó da lista.
      //Depois disso, o nó a ser removido passará a apontar para NULL e será desligado
      //Com essa instrução, noARemover aponta para o nó que será removido já que achamos o elemento do nó
      //a ser removido no while (iterador->proximo->conteudo foi igual ao elemento). Mas lembre que iremos
      //remover o nó como um todo, não apenas o elemento.
      no *noARemover = iterador->proximo;
      //Só conseguimos fazer o nó anterior ao nó que será removido apontar para o nó seguinte ao nó que será
      //removido com essa instrução. Essa é a linha chave da remoção que liga os 2 nós, isolando o nó que será
      //removido.
      iterador->proximo = noARemover->proximo;
      //O nó a ser removido passa a apontar para NULL e é completamente desligado da lista
      noARemover->proximo = NULL;
      free(noARemover);
      //O tamanho da lista é decrementado
      lista->tamanho--;
      printf("
      %d foi removido!
      ", elemento);
      }
      //free(iterador);
      //Perceba que noARemover funciona como um intermediário e facilitador para trabalhar com os ponteiros
      }
      }
      void imprimir(Lista *lista){
      //Criamos um ponteiro do tipo nó que receberá o início da lista para podermos
      //trabalhar com o while imprimindo os elementos e andando na lista
      no *iterador = lista->inicio;
      //Enquanto houverem elementos na lista, os exibiremos na tela e andaremos na lista
      //através do ponteiro criado
      printf("
      Tamanho da lista: %d
      ", lista->tamanho);
      while(iterador != NULL){
      printf("%d
      ", iterador->conteudo);
      iterador = iterador->proximo;
      //O último nó sempre aponta para NULL. Logo, quando o iterador chegar no último nó, ele irá
      //receber iterador->proximo normalmente, mas dessa vez iterador->proximo passa a apontar
      //para o mesmo local que o último nó aponta, ou seja, NULL. Logo, sairemos do loop, fim da lista
      }
      printf("
      ");
      }
      int main(){
      //Criando a lista e alocando memória dinamicamente para ela
      Lista *lista = (Lista*)malloc(sizeof(Lista));
      if (lista == NULL) {
      printf("Erro de alocacao da lista!
      ");
      exit(0);
      } else {
      int quantidade, opcao, valor;
      inicializaLista(lista);
      do {
      printf("
      [1] insere o elemento no inicio
      [2] insere o elemento no fim
      [3] exibir dados
      [4] remover elemento
      [5] sair
      ");
      printf(">>>Sua opcao: ");
      scanf("%d", &opcao);
      switch(opcao){
      //Insere o elemento no inicio
      case 1:
      printf("Digite o valor: ");
      scanf("%d", &valor);
      inserirInicio(valor, lista);
      break;
      //Insere o elemento no fim
      case 2:
      printf("Digite o valor: ");
      scanf("%d", &valor);
      inserirFim(valor, lista);
      break;
      //Exibe os dados da lista
      case 3:
      imprimir(lista);
      break;
      //Remove algum elemento específico verificando se a lista está ou não vazia
      case 4:
      if(lista->inicio == NULL){
      printf("Lista vazia!
      ");
      }else{
      printf("Digite o valor: ");
      scanf("%d", &valor);
      excluir(valor, lista);
      }
      break;
      //Sai do programa liberando a memória alocada para a lista
      case 5:
      free(lista);
      printf("Voce optou por sair...
      ");
      break;
      //Opções inválidas
      default:
      printf("Escolha uma opcao valida!
      ");
      }
      } while (opcao != 5);
      }
      return 0;
      }

    • @JoaoPaulo-zv8ry
      @JoaoPaulo-zv8ry 2 ปีที่แล้ว +1

      PS: por algum motivo a função excluir não funciona completamente no codeblocks, mas no VSCODE sim. Por completamente quero dizer se você tentar remover um elemento que não existe na lista, o codeblocks simplesmente para, ao menos pra mim. No VS, não aconteceu nenhum problema se o programa for compilado tranquilamente.

    • @raulfreire2895
      @raulfreire2895 ปีที่แล้ว +1

      @@JoaoPaulo-zv8ry Cara, sem palavras para te agradecer. Seu código está me ajudando muito! Muito obrigado

  • @BonnieBJr
    @BonnieBJr 2 ปีที่แล้ว +1

    Você explica muito bem! Conteúdo sensacional!

  • @camilamedeiros8282
    @camilamedeiros8282 3 ปีที่แล้ว +1

    ameii, vai mostrar como inserir no meio?

    • @programeseufuturo
      @programeseufuturo  3 ปีที่แล้ว

      Olá Camila.
      Produzi aqui pro canal um curso completo de C, então regravei estas aulas sobre listas encadeadas, elas estão nas playlist sobre estruturas de dados em C a partir da aula 242: th-cam.com/play/PLqJK4Oyr5WSjQ584hwqaHJYDpDcYqS-HK.html