从列表中删除值

Remove value from a List

我正在编写一个程序来创建列表、打印它并从列表中删除(3 个函数)。

Print 和 pushBack 都很好,它们工作得很好,但我不知道如何从 removeFromList() 函数中的列表中取出一个数字。

不要注意名称(如客户端、套接字),这是为了我的客户端-服务器应用程序保存活动套接字(这就是为什么我需要在客户端断开连接时将它们从列表中删除)。

这里我有 2 个结构:listElement 和 clientList(其中包含指向 listElement 的头元素的指针)

struct listElement
{
    SOCKET socket;
    struct listElement* next;
};

struct clientList
{
    listElement * head;
};

我的回推函数:

int pushBackСlient(struct clientList* list, int socket)
{
    struct listElement* newClient = (struct listElement*)malloc(sizeof(struct listElement));
    struct listElement* currentElement = list->head;
    newClient->socket = socket;
    newClient->next = 0;
    do
    {
        // IT'S PUSHBACK
        if (list->head == 0)
        {
            list->head = newClient;
            break;
        }
        while (currentElement->next != 0)
        {
            currentElement = currentElement->next;
        }
        currentElement->next = newClient;
    } while (false);

    return 0;
}

我的打印:

void print(struct clientList* list)
{
    struct listElement* currentElement = list->head;
    while (currentElement != 0)
    {
        printf("%d\n", currentElement->socket);
        currentElement = currentElement->next;
    }
}

我遇到的功能有问题(我制作了调试消息以查看是否正确添加了 "socket")。我想我不需要前 3 行但不确定。

已更新13/05/2017

void removeFromList(struct clientList* list, int socket)
{
    struct listElement* currentElement = list->head;
    do
    {
        if (list->head == 0)
        {
            return;
        }

        while (currentElement != 0 && currentElement->next != 0)
        {
            if (currentElement->socket == socket)
            {
                printf("currentElement == %d\n", currentElement);
                currentElement = currentElement->next;
                printf("currentElement == %d\n", currentElement);
                free(currentElement);
                //break; // if I only want to remove the first socket?
            }
            currentElement = currentElement->next;
        }
    } while (false);
}

谢谢。

对于您的删除功能,我建议如下:

void removeFromList(struct clientList* list, int socket)
{
    struct listElement* aux, prev;
    if(list->head == 0)
        return;

    aux = list->head;
    prev = aux;

    while(aux != 0){
        if(aux->socket == socket) {
            prev->next = aux->next;
            free(aux);
            break; // if you only want to remove the first socket
        }
        prev = aux;
        aux = aux->next;    
    }
} 

至于你的列表结构,我建议使用结构的结构,如下所示:

struct list
{
    int numberOfElements;
    NODE * first;
} LIST;

struct node
{
    ELEMENT * info;
    NODE * prev; // If you want to have a double connection between the nodes
    NODE * next;
} NODE;

struct element
{
    int id;
    /* Other Properties */
} ELEMENT;

它应该能让您更好地控制列表。

函数removeFromList至少是错误的,因为当列表只包含一个元素时,while 语句的这个条件可以等于假。在这种情况下,即使这个元素包含目标 vakue,它也不会被删除。

while (currentElement != 0 && currentElement->next != 0)

功能可以和演示程序中显示的一样。

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

typedef int SOCKET;

struct listElement
{
    SOCKET socket;
    struct listElement *next;
};

struct clientList
{
    struct listElement *head;
};

int pushBackClient( struct clientList *list, SOCKET socket )
{
    struct listElement *newClient = malloc( sizeof( struct listElement ) );
    int success = newClient!= NULL;

    if ( success )
    {
        newClient->socket = socket;
        newClient->next   = NULL;

        struct listElement **current = &list->head;

        while ( *current != NULL ) current = &( *current )->next;

        *current = newClient;
    }

    return success;
}


int removeFromList( struct clientList *list, SOCKET socket )
{
    int success;

    struct listElement **current = &list->head;

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

    if ( ( success = *current != NULL ) )
    {
        struct listElement *tmp = *current;
        *current = ( *current )->next;

        free( tmp );
    }

    return success;
}

void print(struct clientList *list)
{
    for ( struct listElement *current = list->head;
          current != NULL;
          current = current->next )
    {         
        printf( "%d ", current->socket );
    }
}

int main(void) 
{
    const int N = 10;
    struct clientList list = { NULL };

    for ( int i = 0; i < N; i++ ) pushBackClient( &list, i );

    print( &list );
    putchar( '\n' );

    for ( int i = 0; i < N; i++ )
    {
        if ( i % 2 == 0 ) removeFromList( &list, i );
    }

    print( &list );
    putchar( '\n' );

    for ( int i = 0; i < N; i++ )
    {
        if ( i % 2 == 1 ) removeFromList( &list, i );
    }

    print( &list );
    putchar( '\n' );

    return 0;
}

程序输出为

0 1 2 3 4 5 6 7 8 9 
1 3 5 7 9 

您至少需要添加一个函数来释放列表中的所有元素。