如何在C中反向双向链表

时间:2018-10-07 19:42:03

标签: c

我如何扭转这个双向链表?我已经尝试过,但是没有任何结果,当我调用函数Reverse()时,它将所有节点设置为NULL。

这是我对双向链表的第一次尝试,我不知道我是否在做正确的事情。 关于如何改善它的任何建议?

#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;
}

根据您的建议,我会改善我的问题。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

这是根据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;
  }

}

我们循环遍历p(头节点)直到它为NULL,然后将(* p)-> prev与(* p)-> next交换,然后* p等于(* p)-> prev。最后,如果temp不等于NULL,我们将temp-> prev分配给* p。

答案 1 :(得分:0)

反转双向链表的唯一正确方法是修改迭代代码,以便(取决于是否设置了“当前方向”标志)将使用“下一个”还是“最后一个”。

如果您实际上修改了双向链表中的每个元素,那么不妨将缓存从CPU中取出并冲洗掉马桶。