使用标头节点反转双向链表

时间:2017-10-06 08:57:04

标签: c list linked-list

目标是反转包含带有标题节点的单词的双向链表。我使用了标准算法,其中我反转了链接列表的各个节点的左右链接。

这是我写的代码

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

typedef struct node
{
    char data[10];
    struct node *rlink;
    struct node *llink;
}NODE;

NODE* insert(NODE *header,char info[])
{
    NODE *new,*temp;
    temp=header;
    new=(NODE*)malloc(sizeof(NODE));
    strcpy(new->data,info);
    new->rlink=NULL;
    new->llink=NULL; 
    while(temp->rlink!=NULL)
    {
        temp=temp->rlink;
    }
    temp->rlink=new;
    new->llink=temp;
    new->rlink=NULL;
    header->llink=NULL;
    return header;
}

void display(NODE *header)
{
    NODE *temp=header->rlink;
    while(temp!=NULL)
    {
        printf("%s \t",temp->data);
        temp=temp->rlink;
    }
}

void displayr(NODE *header)
{
    NODE *temp=header->rlink;
    while(temp!=NULL)
    {
        printf(" %s \t",temp->data);
        temp=temp->rlink;
    }
}

void main()
{
    int num,i=0;
    char info[10];
    NODE *header;
    header=(NODE*)malloc(sizeof(NODE));
    header->rlink=NULL;
    header->llink=NULL;
    printf("\n Enter the number of strings \n");
    scanf("%d",&num);
    for(i=0;i<num;i++)
    {
        scanf("%s",info);
        header=insert(header,info);
    }
    printf("\n Displaying the original linked list");
    display(header);
    NODE *temp1=header;
    NODE *temp2;
    while(temp1->rlink!=NULL) //Reversing the linked list
    {
        temp2=temp1->rlink;
        temp1->rlink=temp1->llink;
        temp1->llink=temp2;
        temp1=temp2;
    }
    temp1->rlink=temp1->llink;
    temp1->llink=NULL;
    printf("\n Displaying reverse \n");
    display(header);
}

问题在于它没有显示反向链表。

例如,如果我的输入为why so serious,则根本没有输出。

2 个答案:

答案 0 :(得分:1)

您的代码中存在多个问题

  1. 您的链接列表的大小比用户输入的项目数量多一个。
  2. 列表的第一个节点为空(包含)无数据。
  3. 为了计算这一点,您的显示功能从列表的第二个节点开始打印。
  4. 现在回答你问的实际问题:为什么反向链表没有显示

    问题在于标题。最初,它指向了列表的开头。因此,当您交换右指针和左指针时,标头在技术上现在指向列表的最后一个节点。您的新标头变为 temp1 temp1 存储列表所在的节点的地址,因此它扮演标题的角色。

    printf("\n Displaying reverse \n");
    display(temp1);
    

    现在这将部分解决您的问题,因为当您调用函数 display(temp1)时,您会发现列表中缺少一个元素。这是由于我在答案的第一部分中提到的问题。以这样的方式写入显示功能,即它将从第二节点开始打印列表。您可以将其更改为:

    void display(NODE *header)
    {
        NODE *temp=header; //start from the first node itself
        while(temp!=NULL)
        {
            printf("%s \t",temp->data);
            temp=temp->rlink;
        }
    }
    

    但是使用此功能,您还必须更改插入代码,以便在标头中存储第一个值,而不是将标头值保持为空。在当前第一个节点值为空的情况下,显示功能将打印一个额外的制表符空间。

答案 1 :(得分:0)

重申Avantika Saini所说的内容,您阅读时的数据结构如下所示

  

0℃; -H-&GT;为什么
  H&LT; -why-&GT;所以
  为什么&LT; -SO-&GT;严重
  所以&LT; -serious-大于0

     

其中0为NULL
  h是标题
  &lt; - 和 - &gt;是llink和rlink
  否则名称代表节点

逆转后你有

  

为什么&LT; -H-大于0
  所以&LT; -why-&GT; H
  严重&LT; -SO-&GT;为什么
  0℃; -serious-&GT;所以

解决问题

  • 在main中将'header'初始化为NULL,并且不为它分配空的NODE。
  • insert检查输入标头是否为NULL。如果它只是返回新的NODE。否则追加到最后。
  • 请勿跳过display中的第一个元素或遍历列表以进行撤消。
  • 您必须确保在撤消结束时header指向原始列表的末尾(serious NODE)。

在此之后,您的数据结构应该看起来像

  

0℃; - 为什么[标题] - GT;所以
  为什么&LT; -SO-&GT;严重
  所以&LT; -serious-大于0

     

我添加了[header]来显示它指向哪个NODE

逆转之后你应该

  

因此&LT; -why-大于0
  严重&LT; -SO-&GT;为什么
  0℃; -serious [标题] - GT;所以

其他一些建议:

不要将new用作变量名称。实际上,不要使用任何C ++关键字或库函数。如果你必须集成或迁移到C ++,这将避免问题。

你没有释放任何记忆。您需要遍历列表,释放每个NODE。