从C中的链表中删除元素

问题描述 投票:-2回答:3

我正在尝试编写一个函数,该函数正在从链接列表中删除特定元素,但是当我到达该元素时,它会因分段错误而崩溃。这是我的代码的一部分

typedef struct dlist_t {
    int data;
    struct dlist_t *prev, *next;
} dlist_t;

typedef struct list_t {
    dlist_t *head, *tail;
} list_t;

int delElement(list_t *list, int elem) {
    while (list) {
        if ((list->head)->data == elem) {
            list->head->next = list->head->prev;
            list->head->prev = list->head->next;
            free(list);
            return 1;
        }
        list = list->head->next;
    }
    return 0;
}
c linked-list
3个回答
0
投票

我不太确定是什么导致了您的崩溃,但是在这里,我有一个应该工作的代码示例。结构定义:

typedef int item_type;
typedef struct _list* list;

struct node {

    item_type data;
    struct node *next,*prev;

};

struct _list {

    struct node* head;
    struct node* tail;
    int size;
};

删除“元素”的功能


void list_del(list l,item_type data) {

    if (list->size ==0) {
        abort();
    }

    int i=0;
    struct node* head = l->head;

    while(i<list->size){
        if(head->data==data){
            head->prev = head->next;
            l->size -= 1;
            free(head);
            return;
        }else{
            head=head->next;
        }
    }

}

“ item_type”这是一个typedef,如果您有很多函数,并且您不必在意类型。在我们的示例中,根据需要输入int


0
投票

您的函数定义没有意义。例如在此赋值语句中

list = list->head->next;

分配的左侧(类型为list_t)和分配的右侧(类型为dlist_t)中使用了不同类型的对象。

或此电话

free(list);

尝试释放列表,而不只是列表的一个节点。依此类推。

此函数可以按照下面的演示程序所示的以下方式查看。

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

typedef struct dlist_t 
{
    int data;
    struct dlist_t *prev, *next;
} dlist_t;

typedef struct list_t 
{
    dlist_t *head, *tail;
} list_t;

int delElement( list_t* list, int elem )
{
    dlist_t **current = &list->head;

    while ( *current != NULL && ( *current )->data != elem )
    {
        current = &( *current )->next;
    }

    int success = *current != NULL;

    if ( success )
    {
        dlist_t *tmp = *current;

        if ( ( *current )->next != NULL )
        {
            ( *current )->next->prev  = ( *current )->prev;
        }
        else
        {
            list->tail = ( *current )->prev;
        }

        *current = ( *current )->next; 

        free( tmp );
    }

    return success;
}

int pushFront( list_t *list, int elem )
{
    dlist_t *new_node = malloc( sizeof( dlist_t ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->next = list->head;
        new_node->prev = NULL;
        new_node->data = elem;

        if ( list->head != NULL )
        {
            list->head->prev = new_node;
        }
        else
        {
            list->tail = new_node;
        }

        list->head = new_node;
    }

    return success;
}

int pushBack( list_t *list, int elem )
{
    dlist_t *new_node = malloc( sizeof( dlist_t ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->prev = list->tail;
        new_node->next = NULL;
        new_node->data = elem;

        if ( list->tail != NULL )
        {
            list->tail->next = new_node;
        }
        else
        {
            list->head = new_node;
        }

        list->tail = new_node;
    }

    return success;
}

void printList( list_t *list )
{
    for ( dlist_t *current = list->head; current != NULL; current = current->next )
    {
        printf( "%d -> ", current->data );
    }

    puts( "null" );
}


void printReverseList( list_t *list )
{
    for ( dlist_t *current = list->tail; current != NULL; current = current->prev )
    {
        printf( "%d -> ", current->data );
    }

    puts( "null" );
}

int main(void) 
{
    list_t list = { .head = NULL, .tail = NULL };

    const int N = 10;

    for ( int i = 0; i < N; i++ )
    {
        if ( i % 2 == 0 ) pushFront( &list, N / 2 - i / 2 - 1 );
        else pushBack( &list, N / 2 + i / 2 );
    }

    printList( &list );
    printReverseList( &list );

    putchar( '\n' );

    for ( size_t i = 0; i < N; i++ )
    {
        if ( i % 2 == 0 ) delElement( &list, i / 2 );
        else delElement( &list, N - i / 2 - 1 );

        printList( &list );
        printReverseList( &list );

        putchar( '\n' );
    }       

    return 0;
}

程序输出为

0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> null

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> null

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> null
8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> null

2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> null
8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> null

2 -> 3 -> 4 -> 5 -> 6 -> 7 -> null
7 -> 6 -> 5 -> 4 -> 3 -> 2 -> null

3 -> 4 -> 5 -> 6 -> 7 -> null
7 -> 6 -> 5 -> 4 -> 3 -> null

3 -> 4 -> 5 -> 6 -> null
6 -> 5 -> 4 -> 3 -> null

4 -> 5 -> 6 -> null
6 -> 5 -> 4 -> null

4 -> 5 -> null
5 -> 4 -> null

5 -> null
5 -> null

null
null

玩程序并进行调查。

[不要忘记编写自己的函数来释放列表中所有已分配的节点。


-1
投票

不用担心,只需尝试一下此代码。这是最简单的实现,可以删除链表中的节点,如果您遇到任何问题,也可以随时提出。

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

struct Node
{
   int data;
   struct Node *next;
}*first=NULL;

void create(int A[],int n)
{
   int i;
   struct Node *t,*last;
   first=(struct Node *)malloc(sizeof(struct Node));
   first->data=A[0];
   first->next=NULL;
   last=first;

 for(i=1;i<n;i++)

 {
   t=(struct Node*)malloc(sizeof(struct Node));
   t->data=A[i];
   t->next=NULL;
   last->next=t;
   last=t;
 }

}

void Display(struct Node *p)
{
   while(p!=NULL)
   {
      printf("%d ",p->data);
      p=p->next;
   }
}

void RDisplay(struct Node *p)

{
  if(p!=NULL)
  {
      RDisplay(p->next);
      printf("%d ",p->data);

  }
}

int Delete(struct Node *p,int index)
{
   struct Node *q=NULL;
   int x=-1,i;

 if(index < 1 || index > count(p))
 return -1;

 if(index==1)
 {
    q=first;
    x=first->data;
    first=first->next;
    free(q);
    return x;
 }

 else
 {
   for(i=0;i<index-1;i++)
   {
       q=p;
       p=p->next;
   }
   q->next=p->next;
   x=p->data;
   free(p);
   return x;

 }


}

int main()
{

    int A[]={10,20,30,40,50};
    create(A,5);

    printf(“%d\n",Delete(first),2);
    Display(first);

    return 0;
}

因此,我们首先使用malloc函数创建了链表。我们创建了一个带有变量的结构,该结构将建立链接列表,即“ data”,还创建了struct类型的pointer

然后,我们创建了一个函数名称“ create”来创建我们的第一个节点。并根据它插入值。

然后您可以看到我们g =已用于循环,以将创建链接列表的过程固定到n的值。

然后显示链接列表,我们已经创建了函数名称“ Display”

如果p!= NULL,即包含地址的节点最后一列,则使用for循环打印该节点的值/数据。

然后为了删除,我们使用了函数名称“ Delete”

[第一步]]:我们是否需要一个指向第一个节点的指针“ p”。

第二步骤:现在首先移至下一个节点。

第三步:现在将已删除节点的值存储在新变量“ x”中。

第四步:删除p

剩余的代码用于通过使用两个指针,前一个节点的一个指针,当前节点的下一个指针],从特定位置删除该节点。

只需尝试一下,或将您的代码错在哪里就可以进行交叉检查。

© www.soinside.com 2019 - 2024. All rights reserved.