简体   繁体   中英

How to reverse a doubly linked list in c

How can i reverse this doubly linked list? I've tried it but whitout any result, when i call the function Reverse() , it set all the nodes to NULL.

This is my first attempt on doubly linked list and i don't know if i'm doing everything the right way. Any suggestions on how to make it better?

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


struct Prova
{
  char nome[16];
  int id;
};

typedef struct Node {
  struct Prova struttura;
  struct Node * next;
  struct Node *prev;

}TNodo;
typedef TNodo* Nodo;



void NuovaPrenotazione(struct Prova  p, Nodo *pp)
{
  Nodo temp;

  temp = (Nodo)malloc(sizeof(struct Node));

  temp->struttura = p;
  temp->next = *pp;
  temp->prev = NULL;

  if(*pp != NULL)
  {
    (*pp)->prev = temp;
  }

  *pp = temp;

}

void LeggiPrenotazione(struct Prova * p)
{
  printf("\nNome Cliente:");
  scanf(" %s", p->nome);
  printf("\nID:");
  scanf(" %d", &p->id);
}


void VisualizzaPrenotazione(Nodo nodo)
{
  Nodo temp;
  while(nodo != NULL)
  {
    temp = nodo->prev;
    if(nodo->prev == NULL)
      {
        printf("Prev = NULL\n");
      }
    else
    {
    printf("Prev:%s %d\n", temp->struttura.nome, temp->struttura.id);
    }
    printf("Curr:%s %d\n", nodo->struttura.nome, nodo->struttura.id);
    nodo = nodo->next;
  }

}

void Reverse(Nodo * p)
{
  Nodo temp;
  while(*p != NULL)
  {
    temp = (*p)->prev;
    (*p)->prev = (*p)->next;
    (*p)->next = temp;
    *p = (*p)->next;
  }


}


int Menu()
{
  int scelta;

  printf("*** M E N U ***\n"
     "1 - Nuova prenotazione\n"
     "2 - Stampa prenotazioni\n"
   "3 - Reverse\n"
   "0 - Esci\n"
  "Scelta --> ");
  scanf(" %d", &scelta);

  return scelta;
}



int main()
{
  int scelta;
  struct Prova test;
Nodo lista = NULL;
  do {
    scelta = Menu();

    switch (scelta)
    {
      case 1:  LeggiPrenotazione(&test);
               NuovaPrenotazione(test, &lista);
      break;
      case 2: VisualizzaPrenotazione(lista); break;
      case 3: Reverse(&lista); break;
      default: scelta = 0;
    }

  } while (scelta != 0);

  return 0;
}

I will improve my question based on your suggestions. Any help would be appreciated.

This is the correct method to reverse a linked list according to geeksforgeeks: https://www.geeksforgeeks.org/reverse-a-doubly-linked-list/

void Reverse(Nodo * p)
{
  Nodo temp = NULL;

  while(*p != NULL)
  {
    temp = (*p)->prev;
    (*p)->prev = (*p)->next;
    (*p)->next = temp;
    *p = (*p)->prev;
  }

  if(temp != NULL)
  {
    *p = temp->prev;
  }

}

We loop throug p (the head node) until it's NULL, we swap (*p)->prev with (*p)->next and then *p is equal to (*p)->prev. Finally if temp is not equal to NULL we assign temp->prev to *p.

The only correct way to reverse a doubly linked list is to modify your iteration code so that (depending on whether a "current direction" flag is set or clear) it will use "next" or "last".

If you actually modify each element of the doubly linked list, then you might as well rip the cache out of your CPU and flush it down the toilet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM