【问题标题】:Linked List reversal in C not workingC中的链表反转不起作用
【发布时间】:2015-08-13 12:21:55
【问题描述】:

我想在 C 语言中对链表进行一些操作。我为此编写了一些函数,例如 - 在开头插入、在尾部插入、从开头删除等。在我的代码中,我尝试实现链表的反转。但它没有按预期工作。它总是只打印第一个值。

#include<stdio.h>
#include<stdlib.h>
struct node
{
    int data;
    struct node *link;
}*new_node,*ptr,*head = NULL,*tmp;

void create_list(int data)
{
    new_node = (struct node*) malloc(sizeof(struct node));
    head = new_node;
    new_node->link=NULL;
    new_node->data=data;
}

void insert_beginning(int data)
{

    if(head==NULL)
    {
        create_list(data);
    }
    else
    {
        new_node = (struct node*) malloc(sizeof(struct node));
        new_node->link = head;
        new_node->data=data;
        head=new_node;
    }
}
void insert_tail(int data)
{
    if(head==NULL)
    {
        create_list(data);
    }
    else
    {
        new_node = (struct node*) malloc(sizeof(struct node));
        ptr = head;
        while(ptr->link!=NULL)
        {
            ptr=ptr->link;
        }
        new_node->link = NULL;
        new_node->data=data;
        ptr->link=new_node;
    }
}
void insert_any_position(int data)
{
    int pos;
    printf("\nEnter the position: ");
    scanf("%d",&pos);
    if(pos==1)
    {
        insert_beginning(data);
    }
    else
    {
        int i=1;
        new_node = (struct node*) malloc(sizeof(struct node));
        ptr = head;
        while(ptr->link!=NULL&&i<(pos-1))
        {
            ptr=ptr->link;
            i++;
        }
        new_node->link = ptr->link;
        new_node->data=data;
        ptr->link=new_node;
    }
}
void insert_node()
{
    int choice,data;
    printf("\n1.Insert at beginning\n2.Insert at tail\n3.Insert at any position\n4.Exit\n");
    scanf("%d",&choice);
    if(choice<4)
    {
        printf("\nEnter the data to be inserted: ");
        scanf("%d",&data);
        switch(choice)
        {
        case 1:
            insert_beginning(data);
            break;
        case 2:
            insert_tail(data);
            break;
        case 3:
            insert_any_position(data);
            break;
        default:
            return;
        }
    }
    else
        return;

}

void delete_beginning()
{
    head = head->link;
}

void delete_tail()
{
    ptr=head;
    while(ptr->link!=NULL)
    {
        tmp=ptr;
        ptr=ptr->link;
    }
    tmp->link=NULL;
}
void delete_any_position()
{   int pos;
    printf("\nEnter the position: ");
    scanf("%d",&pos);
    if(pos==1)
    {
        delete_beginning();
    }
    else
    {
        ptr=head;
        int i=1;
        while(ptr->link!=NULL && i<(pos-1))
        {
            ptr=ptr->link;
            i++;
        }
        ptr->link=(ptr->link)->link;
    }

}
void delete_data()
{

}

void delete_node()
{
    int choice,data;
    printf("\n1.Delete from beginning\n2.Delete from tail\n3.Delete from any position\n4.Delete data\n5.Exit\n");
    scanf("%d",&choice);
    if(choice<5)
    {

        switch(choice)
        {
        case 1:
            delete_beginning();
            break;
        case 2:
            delete_tail();
            break;
        case 3:
            delete_any_position();
            break;
        case 4:
            printf("\nEnter the data to be deleted: ");
            scanf("%d",&data);
            delete_data(data);
            break;
        default:
            return;
        }
    }
    else
        return;
}
void display_list()
{
    ptr = head;
    while(ptr!=NULL)
    {
        printf("%d ",ptr->data);
        ptr = ptr->link;
    }
}

void display_list_recursion(struct node* ptr)
{
    if(ptr==NULL)
        return;
    else
    {
        printf("%d ",ptr->data);
        display_list_recursion(ptr->link);
    }
}
void display_list_recursion_reverse(struct node* ptr)
{
    if(ptr==NULL)
        return;
    else    
    {
        display_list_recursion_reverse(ptr->link);
        printf("%d ",ptr->data);
    }   

}

这是不起作用的功能:

void reverse_list_iteration()
{
    struct node *current,*prev,*next;
    current=head;
    prev=NULL;
    while(current->link!=NULL)
    {
        next = current->link;
        current->link = prev;
        prev=current;
        current=next;
    }
    head=prev;
}

main()
{
    int choice;
    do
    {
        printf("\nEnter your choice\n1.Insert\n2.Delete\n3.Display\n4.Display using recursion");
        printf("\n5.Display Reverse\n6.ReverseListIteration\n7.Exit\n\t\t\t");
        scanf("%d",&choice);
        switch(choice)
        {
        case 1:
            insert_node();
            break;
        case 2:
            delete_node();
            break;
        case 3:
            display_list();
            break;
        case 4:display_list_recursion(head);
            break;
        case 5:display_list_recursion_reverse(head);
            break;
        case 6:reverse_list_iteration();
            break;
        case 7:
            exit(0);
        }
    }
    while(choice<7);
}

其他功能正在运行。在调用reverse_list_iteration() 之后调用display_list() 它只显示一个数据。我认为某些链接已损坏,但我无法弄清楚。

【问题讨论】:

  • 是否有一些课堂规则只使用您受到限制的全局变量,因为它确实是您应该努力争取的确切相反
  • 当列表只包含一个元素时尝试reverse_list_iteration。先解决这个问题。
  • 不要将new_node创建为全局变量;它应该在每个函数中都是本地的。尽可能避免使用全局变量。此外,您至少应该遵守 C99,最好是 C11,这意味着您需要在 int main() 上明确返回类型,或者最好是 int main(void),尽管两者都可以工作并且本质上是等价的。创建 MCVE (How to create a Minimal, Complete, and Verifiable Example?) 也是一个好主意。你所拥有的相当完整,但不是最少的。

标签: c linked-list singly-linked-list


【解决方案1】:

只需将reverse_list_iteration() 中的current-&gt;link!=NULL 更改为current!=NULL,您的问题就解决了。

希望对您有所帮助。编码愉快。

【讨论】:

  • 我测试了 chux 的修复并确认它有效。在调试链表时,我曾经发现有用的一件事是打印指针地址。对于 Sarath 的问题,我尝试对名为 display_list() 的函数进行此修改----printf("head:%p\n",head); while(ptr!=NULL) { printf("node:%p link:%p data:%d \n",ptr,ptr-&gt;link,ptr-&gt;data); ptr = ptr-&gt;link; }
  • @donbright 我试过了,是的,它有助于调试链接列表,并且很高兴观察反转列表后链接的变化。
猜你喜欢
  • 2014-07-30
  • 2020-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-30
  • 2016-03-19
  • 1970-01-01
相关资源
最近更新 更多