【问题标题】:Error in program to delete the last occurence of a an element in linked list删除链表中最后一次出现的元素的程序出错
【发布时间】:2021-02-25 04:10:37
【问题描述】:

目的是制作一个程序,删除链表中最后一次出现的元素 例如:-如果链表是 23->45->23->24->23 然后我寻找输出 23->45->23->24 但是我在调​​试时遇到了几个错误,主要是在 temp->next!=NULL 和 t1->next=t->next 部分,请指出阻碍程序执行的错误?

#include<stdio.h>
#include<stdlib.h>
struct node
{
    int data;
    struct node *next;
};
void insertLL(struct node *head,int data)
{
    struct node *temp;
    struct node *new=(struct node *)malloc(sizeof(struct node));
    new->data=data;
    if(head==NULL)
    {
        head=new;
    }
    else
    {
        temp=head;   
        while(temp->next!=NULL)
        {
            temp=temp->next;
        }
        temp->next=new;
    }
}
void delete(struct node *head,int data)
{
    struct node *temp=head;
    struct node *t;
    struct node *t1;
    while(temp->next!=NULL)
    {
        if(temp->next->data==data)
        {
            t1=temp;
        }
        if(temp->data==data)
        {
            t=temp;
        }
        temp=temp->next;
    }
    t1->next=t->next;
    free(t);
}
void display(struct node *head)
{
    struct node *temp1=head;
    if (head==NULL)
    {
        printf("List is empty");
    }
    else
    {
        while(temp1->next!=NULL)
        {
            printf("%d",temp1->data);
            printf("->");
            temp1=temp1->next;
        }
    }
    
}
int main()
{
    int u,k,l,n;
    struct node *start;
    while(1)
    {
        printf("Press 1 to insert element into the Linked List, press 2 to delete the last occurence of an element from a linked list, press 3 to display the linked list, press 0 to exit the program\n");
        scanf("%d",&u);
        switch(u)
        {
            case 1:
            {
                printf("Enter the data you want to insert\n");
                scanf("%d",&l);
                insertLL(start,l);
                break;
            }
            case 2:
            {
                printf("Enter the element that you want to be deleted\n");
                scanf("%d",&k);
                delete(start,k);
                break;
            }
            case 3:
            {
                display(start);
                break;
            }
            default:
            {
                printf("Invalid input\n");
            }
            
        }
        printf("Enter 1 to continue or 0 to break\n");
        scanf("%d",&n);
        if(n==1)
        {
            continue;
        }
        if(n==0)
        {
            break;
        }
    }
}

【问题讨论】:

  • 请告诉我们您遇到了什么错误或问题。即给出准确的输入、预期结果和实际结果。
  • 是的,我通过调试器运行了代码,如果链表是 23->45->23->24->23 那么我寻找输出 23->45->23 ->24 但我在 temp->next!=NULL 和 t1->next=t->next 行的删除函数中遇到分段错误
  • edit提供该信息的问题。
  • 一个主要问题:head=new; 那行不通。 head 是一个局部变量,因为函数参数是在 C 中传递的值。更改该值不会更改调用者的变量。
  • 那么我应该全局初始化struct node *start,然后直接初始化新的节点start吗?

标签: c struct linked-list singly-linked-list function-definition


【解决方案1】:

对于初学者来说,函数insertLL 是不正确的,因为它处理指向头节点的指针值的副本。即更改副本不会影响原始对象。

你需要通过指向头节点的指针来传递指向头节点的指针。

函数可以通过以下方式声明和定义。

int insertLL( struct node **head, int data )
{
    struct node *new_node = malloc( sizeof( struct node ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->data = data;
        new_node->next = NULL;

        while ( *head ) head = &( *head )->next;
  
        *head = new_node;
    }

    return success;
}

并且函数可以像这样调用

insertLL( &start, data );

if ( !insertLL( &start, data ) )
{
    puts( "Error: not enough memory." );
}

函数delete 也不正确。例如,当由于此语句而为空列表调用它时,它可以调用未定义的行为

while(temp->next!=NULL)

函数可以通过以下方式声明和定义

void delete( struct node **head, int data )
{
    // Find the last node with the target data
    struct node **target = NULL;

    while ( *head )
    {
        if ( ( *head )->data == data )
        {
            target = head;
        }
    }

    // If the target node is found remove it from the list
    if ( target != NULL )
    {
        struct node *tmp = *target;
        *target = ( *target )->next;
        free( tmp );
    }
}

而功能显示又不正确。由于此语句,列表仅包含一个节点时它不输出任何内容

while(temp1->next!=NULL)

函数可以通过以下方式声明和定义

void display( const struct node *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d -> ", head->data );
    }

    puts( "null" );
}

主要是这些陈述

        default:
        {
            printf("Invalid input\n");
        }

    printf("Enter 1 to continue or 0 to break\n");
    scanf("%d",&n);
    if(n==1)
    {
        continue;
    }
    if(n==0)
    {
        break;
    }

是多余的。你已经写给用户如何退出循环了

printf("Press 1 to insert element into the Linked List, press 2 to delete the last occurence of an element from a linked list, press 3 to display the linked list, press 0 to exit the program\n");

所以循环可以看起来像

while(1)
{
    printf("Press 1 to insert element into the Linked List, press 2 to delete the last occurence of an element from a linked list, press 3 to display the linked list, press 0 to exit the program\n");

    u = -1;
    scanf("%d",&u);

    switch(u)
    {
        case 1:
        {
            //...
            break;
        }
        case 2:
        {
            //...
            break;
        }
        case 3:
        {
            //...
            break;
        }
        default:
        {
            if ( u != 0 )
            {
                printf("Invalid input\n");
            }
            break;
        }
    }

    if ( u == 0 ) break;
}

【讨论】:

    猜你喜欢
    • 2020-08-13
    • 2015-11-04
    • 2020-03-16
    • 1970-01-01
    • 2015-12-12
    • 2023-03-16
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多